From 2cc9605fe19184a4fdc921b1536acf1a0c21131c Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Mon, 15 Jun 2015 15:24:24 +0200 Subject: [PATCH 001/167] added new startline advantage widget ui component --- .../RibDashboard.css | 8 +- .../gwt/client/RibDashboardPanel.java | 8 +- .../gwt/client/RibDashboardPanel.ui.xml | 14 +- .../gwt/client/RibDashboardService.java | 3 + .../gwt/client/RibDashboardServiceAsync.java | 2 + .../dashboards/gwt/client/Ribstyle.css | 2 +- .../actions/GetStartlineAdvantagesAction.java | 29 ++ .../startanalysis/StartlineAnalysisCard.java | 2 +- .../LiveAverageComponent.css | 4 +- .../StartLineAdvantageComponent.java | 4 +- .../StartlineAdvantagesByWindComponent.java | 66 +++++ .../StartlineAdvantagesByWindComponent.ui.xml | 17 ++ ...tartlineAdvantagesByWindComponentStyle.css | 20 ++ .../StartlineAdvantagesOnLineChart.java | 267 ++++++++++++++++++ .../StartlineAdvantagesOnLineChart.ui.xml | 11 + .../StartlineAdvantagesOnLineChartStyle.css | 19 ++ .../gwt/server/RibDashboardServiceImpl.java | 15 + .../sailing/gwt/ui/client/StringMessages.java | 9 +- .../gwt/ui/client/StringMessages.properties | 7 +- .../ui/client/StringMessages_de.properties | 7 +- .../ui/client/StringMessages_ru.properties | 7 +- .../ui/client/StringMessages_zh.properties | 7 +- 22 files changed, 504 insertions(+), 24 deletions(-) create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.ui.xml create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css diff --git a/java/com.sap.sailing.dashboards.gwt/RibDashboard.css b/java/com.sap.sailing.dashboards.gwt/RibDashboard.css index cb096f5372f..b9dadd666b0 100644 --- a/java/com.sap.sailing.dashboards.gwt/RibDashboard.css +++ b/java/com.sap.sailing.dashboards.gwt/RibDashboard.css @@ -22,11 +22,9 @@ } .highcharts-container { - position: absolute; - top: 0pt; - bottom: 0pt; - left: 0pt; - right: 0pt; + position: absolute !important; + width: 100% !important; + height: 100% !important; } .bottomnotification { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java index f427de40676..0dc6416b7d3 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java @@ -24,7 +24,7 @@ import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverP import com.sap.sailing.dashboards.gwt.client.eventlogo.EventLogo; import com.sap.sailing.dashboards.gwt.client.notifications.WrongDeviceOrientationNotification; import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisComponent; -import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartLineAdvantageComponent; +import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartlineAdvantagesByWindComponent; import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; @@ -63,9 +63,9 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr @UiField HTMLPanel rightwindbotcontainer; - + @UiField(provided = true) - public StartLineAdvantageComponent startLineCAComponent; + StartlineAdvantagesByWindComponent startlineAdvantagesByWindComponent; @UiField public DivElement windloadinghintleft; @@ -90,7 +90,7 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr windBotComponents = new ArrayList(); ribDashboardDataRetriever.addDataObserver(this); startanalysisComponent = new StartlineAnalysisComponent(ribDashboardService, sailingServiceAsync); - startLineCAComponent = new StartLineAdvantageComponent(ribDashboardDataRetriever); + startlineAdvantagesByWindComponent = new StartlineAdvantagesByWindComponent(ribDashboardService); stringConstants = StringMessages.INSTANCE; initWidget(uiBinder.createAndBindUi(this)); initLogos(); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml index f0aec9e2f90..bbf6cf92eef 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml @@ -18,11 +18,15 @@ -
+
+
+
-
+
+
+
@@ -33,8 +37,10 @@ - + + + diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java index 7008db01a11..9632463f7ce 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java @@ -7,6 +7,7 @@ import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sse.common.Util.Pair; public interface RibDashboardService extends RemoteService { RibDashboardRaceInfoDTO getLiveRaceInfo(String leaderboardName) throws NoWindException; @@ -14,4 +15,6 @@ public interface RibDashboardService extends RemoteService { List getStartAnalysisListForCompetitorIDAndLeaderboardName(String competitorIdAsString, String leaderboardName); List getCompetitorsInLeaderboard(String leaderboardName); + + List> getAdvantagesOnStartline(String leaderboardName); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java index 755245d6800..14f5e7d8c1a 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java @@ -6,6 +6,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sse.common.Util.Pair; public interface RibDashboardServiceAsync { @@ -15,4 +16,5 @@ public interface RibDashboardServiceAsync { void getCompetitorsInLeaderboard(String leaderboardName, AsyncCallback> callback); + void getAdvantagesOnStartline(String leaderboardName, AsyncCallback>> callback); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css index 14b4df0e958..d59bc127c64 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css @@ -136,7 +136,7 @@ top: 0pt; right: 0pt; left: 0pt; - bottom: 70%; + bottom: 30%; margin-bottom: 5pt; } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java new file mode 100644 index 00000000000..112b76cd824 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java @@ -0,0 +1,29 @@ +package com.sap.sailing.dashboards.gwt.client.actions; + +/** + * @author Alexander Ries (D062114) + * + */ + +import java.util.List; + +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; +import com.sap.sse.common.Util.Pair; +import com.sap.sse.gwt.client.async.AsyncAction; + +public class GetStartlineAdvantagesAction implements AsyncAction>> { + + private final RibDashboardServiceAsync ribDashboardService; + private final String leaderboardName; + + public GetStartlineAdvantagesAction(RibDashboardServiceAsync ribDashboardService, String leaderboardName) { + this.ribDashboardService = ribDashboardService; + this.leaderboardName = leaderboardName; + } + + @Override + public void execute(AsyncCallback>> callback) { + ribDashboardService.getAdvantagesOnStartline(leaderboardName, callback); + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java index 034fd34c083..af342b7a6cb 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysisCard.java @@ -97,7 +97,7 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star .equals(StartlineAdvantageType.GEOMETRIC)) { startLineAdvantageType = stringMessages.dashboardStartlineAdvantageByGeometry(); }else{ - startLineAdvantageType = stringMessages.dashboardStartlineAdvantageByWind(); + startLineAdvantageType = stringMessages.dashboardStartlineAdvantagesByWind(); } startanalysis_card_line_advantage .setInnerHTML(startLineAdvantageType diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css index 5bee6ef9130..7eb53bbd5f2 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css @@ -61,7 +61,7 @@ .liveAverageCompoment_panel_value_unit { font-family: 'Open Sans', Arial, Verdana, sans-serif; - font-size: 12pt; + font-size: 11pt; } .liveAverageCompoment_panel_value_unit_degrees { @@ -84,7 +84,7 @@ width: 100%; height: 100%; text-align: center; - font-size: 12pt; + font-size: 11pt; color: grey; font-family: 'Open Sans', Arial, Verdana, sans-serif; } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java index 03ebbcb4ae7..b0088e19a06 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java @@ -29,7 +29,7 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements stringConstants = StringMessages.INSTANCE; initAndSetStartLineAdvantageStates(); StartLineAdvantageComponentRessources.INSTANCE.css().ensureInjected(); - this.header.setInnerText(stringConstants.dashboardStartlineAdvantageByWind()); + this.header.setInnerText(stringConstants.dashboardStartlineAdvantagesByWind()); this.header.addClassName(StartLineAdvantageComponentRessources.INSTANCE.css() .startLineAdvantageComponent_header()); liveAveragePanel.getElement().addClassName( @@ -116,7 +116,7 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements @Override public void changeStartLineAdvatageComponentsStateToOtherState( StartLineAdvantageComponent startLineAdvantageComponent) { - startLineAdvantageComponent.header.setInnerText(stringConstants.dashboardStartlineAdvantageByWind()); + startLineAdvantageComponent.header.setInnerText(stringConstants.dashboardStartlineAdvantagesByWind()); startLineAdvantageComponent.startLineAdvantageComponentState = startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByGeometry; startLineAdvantageComponent.liveNumber .setInnerText(startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByGeometry diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java new file mode 100644 index 00000000000..cd6bb5edbc5 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java @@ -0,0 +1,66 @@ +package com.sap.sailing.dashboards.gwt.client.startlineadvantage; + +import java.util.Iterator; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HasWidgets; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; + +/** + * @author Alexander Ries (D062114) + * + */ +public class StartlineAdvantagesByWindComponent extends Composite implements HasWidgets { + + private static StartlineAdvantagesByWindComponentUiBinder uiBinder = GWT + .create(StartlineAdvantagesByWindComponentUiBinder.class); + + interface StartlineAdvantagesByWindComponentUiBinder extends UiBinder { + } + + interface StartlineAdvantagesByWindComponentStyle extends CssResource { + + } + + @UiField(provided = true) + LiveAverageComponent advantageMaximumLiveAverage; + + @UiField(provided = true) + StartlineAdvantagesOnLineChart startlineAdvantagesOnLineChart; + + @UiField + StartlineAdvantagesByWindComponentStyle style; + + public StartlineAdvantagesByWindComponent(RibDashboardServiceAsync ribDashboardService) { + startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart(ribDashboardService); + advantageMaximumLiveAverage = new LiveAverageComponent(StringMessages.INSTANCE.dashboardStartlineAdvantagesByWind(), "s"); + initWidget(uiBinder.createAndBindUi(this)); + advantageMaximumLiveAverage.updateValues("55", "43"); + } + + @Override + public void add(Widget w) { + throw new UnsupportedOperationException("The method add(Widget w) is not supported."); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("The method clear() is not supported."); + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public boolean remove(Widget w) { + return false; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.ui.xml new file mode 100644 index 00000000000..6bd79c479e9 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.ui.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css new file mode 100644 index 00000000000..c1e629ef0df --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; + +.startline_advantages_by_wind_component_container{ + position: absolute; + height: 100%; + width: 100%; +} + +.advantage_maximum_live_average{ + position: absolute; + height: 30%; + width: 100%; +} + +.advantages_on_line_chart_container{ + position: absolute; + height: 70%; + top: 30%; + width: 100%; +} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java new file mode 100644 index 00000000000..2334a3b4fa4 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java @@ -0,0 +1,267 @@ +package com.sap.sailing.dashboards.gwt.client.startlineadvantage; + +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import org.moxieapps.gwt.highcharts.client.Animation; +import org.moxieapps.gwt.highcharts.client.Animation.Easing; +import org.moxieapps.gwt.highcharts.client.AxisTitle; +import org.moxieapps.gwt.highcharts.client.Chart; +import org.moxieapps.gwt.highcharts.client.Credits; +import org.moxieapps.gwt.highcharts.client.Legend; +import org.moxieapps.gwt.highcharts.client.PlotLine.DashStyle; +import org.moxieapps.gwt.highcharts.client.Point; +import org.moxieapps.gwt.highcharts.client.Series; +import org.moxieapps.gwt.highcharts.client.Style; +import org.moxieapps.gwt.highcharts.client.ToolTip; +import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsData; +import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsFormatter; +import org.moxieapps.gwt.highcharts.client.labels.XAxisLabels; +import org.moxieapps.gwt.highcharts.client.labels.YAxisLabels; +import org.moxieapps.gwt.highcharts.client.plotOptions.AreaPlotOptions; +import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.HasWidgets; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; +import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesAction; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.common.Util.Pair; +import com.sap.sse.gwt.client.async.AsyncActionsExecutor; +import com.sap.sse.gwt.client.player.TimeListener; +import com.sap.sse.gwt.client.player.Timer; +import com.sap.sse.gwt.client.player.Timer.PlayModes; + +/** + * @author Alexander Ries (D062114) + * + */ +public class StartlineAdvantagesOnLineChart extends Composite implements HasWidgets, TimeListener { + + private static StartlineAdvantagesOnLineChartUiBinder uiBinder = GWT.create(StartlineAdvantagesOnLineChartUiBinder.class); + + interface StartlineAdvantagesOnLineChartUiBinder extends UiBinder { + } + + interface StartlineAdvantagesOnLineChartStyle extends CssResource { + } + + @UiField + HTMLPanel chartContainer; + + private RibDashboardServiceAsync ribDashboardService; + private AsyncActionsExecutor asyncActionsExecutor; + private String leaderboardName; + private Chart chart; + private Series series; + + private static final String PARAM_LEADERBOARD_NAME = "leaderboardName"; + + public StartlineAdvantagesOnLineChart(RibDashboardServiceAsync ribDashboardService) { + this.ribDashboardService = ribDashboardService; + this.asyncActionsExecutor = new AsyncActionsExecutor(); + this.leaderboardName = Window.Location.getParameter(PARAM_LEADERBOARD_NAME); + initWidget(uiBinder.createAndBindUi(this)); + initAndAddChart(); + + //TODO Remove and centralize data retrieving + initSampleTimer(); + } + + private void initSampleTimer(){ + Timer timer = new Timer(PlayModes.Live); + timer.setRefreshInterval(3000); + timer.addTimeListener(this); + timer.play(); + } + + private void initAndAddChart() { + chart = initChart(); + setCorrectChartSpacing(chart); + setXAxisOfChart(chart); + setYAxisOfChart(chart); + series = createSeries(chart); + chart.addSeries(createSeries(chart)); + chartContainer.add(chart); + } + + private Chart initChart(){ + Chart chart = new Chart() + .setType(Series.Type.AREA) + .setChartTitleText(null) + .setLegend(new Legend().setEnabled(false)) + .setToolTip(new ToolTip().setEnabled(false)) + .setCredits(new Credits().setEnabled(false)) + .setStyle(new Style().setPosition("absolute").setTop("0px").setBottom("0px").setLeft("0px").setRight("0px")) + .setAnimation(true); + chart.setSize("100%", "100%"); + chart.setSizeToMatchContainer(); + return chart; + } + + /** + * Highcharts default chart element spacing is not consistent + * so there is a need to correct the right spacing + * of the chart to make it look visually right. + * */ + private void setCorrectChartSpacing(Chart chart){ + chart.setSpacingTop(17) + .setSpacingBottom(13) + .setSpacingRight(35); + } + + private void setXAxisOfChart(Chart chart){ + chart.getXAxis() + .setAxisTitle(new AxisTitle().setText(StringMessages.INSTANCE.dashboardDistanceToRCBoat()).setStyle(new Style().setFontFamily("Open Sans") + .setFontSize("14") + .setColor("black").setFontWeight("bold"))) + .setLabels(new XAxisLabels() + .setFormatter(new AxisLabelsFormatter() { + public String format(AxisLabelsData axisLabelsData) { + return getAxisLabelValueForLabelData(axisLabelsData.getValueAsLong()); + } + } + ).setStyle(new Style().setFontFamily("Open Sans") + .setFontSize("12") + .setColor("grey"))) + .setLineWidth(1) + .setLineColor("grey") + .setTickColor("grey") + .setTickWidth(1) + .setReversed(true); + } + + private void setYAxisOfChart(Chart chart){ + chart.getYAxis() + .setAxisTitle(new AxisTitle().setText(StringMessages.INSTANCE.dashboardAdvantageInSeconds()).setStyle(new Style().setFontFamily("Open Sans") + .setFontSize("14") + .setColor("black").setFontWeight("bold"))) + .setLabels(new YAxisLabels() + .setFormatter(new AxisLabelsFormatter() { + public String format(AxisLabelsData axisLabelsData) { + return String.valueOf(axisLabelsData.getValueAsLong()); + } + } + ).setStyle(new Style().setFontFamily("Open Sans").setFontSize("12") + .setColor("grey"))).setLineColor("grey").setTickWidth(1).setTickColor("grey").setLineWidth(1).setGridLineWidth(0); + } + + private Series createSeries(Chart chart){ + Series series = chart + .createSeries() + .setName(null) + .setPlotOptions( + new AreaPlotOptions().setDashStyle(DashStyle.SOLID).setLineWidth(1) + .setMarker(new Marker().setEnabled(false)).setShadow(false).setHoverStateEnabled(false) + .setLineColor("#008FFF").setFillColor("#008FFF")); + return series; + } + + private String getAxisLabelValueForLabelData(double labelData) { + String result = String.valueOf(labelData); + com.sap.sse.common.Util.Pair firstAndLastXValue = getFirstnAndLastXValueOfSeries(); + if (firstAndLastXValue != null && firstAndLastXValue.getA() != null && firstAndLastXValue.getB() != null) { + if (labelData == firstAndLastXValue.getA().doubleValue()) { + result = StringMessages.INSTANCE.dashboardRCBoat(); + } else if (labelData == firstAndLastXValue.getB().doubleValue()) { + result = StringMessages.INSTANCE.dashboardPinEnd(); + } + } + return result; + } + + private com.sap.sse.common.Util.Pair getFirstnAndLastXValueOfSeries(){ + if(series != null && + series.getPoints() != null && + series.getPoints().length > 1){ + Double firstValue = new Double(series.getPoints()[0].getX().doubleValue()); + Double lastValue = new Double(series.getPoints()[series.getPoints().length-1].getX().doubleValue()); + com.sap.sse.common.Util.Pair firstAndLastXValue = new Pair(firstValue, lastValue); + return firstAndLastXValue; + }else{ + return null; + } + } + + /** + * Removed all Points and adds new ones + * */ + private void updateSeriesPoints(List> xYPairs) { + if (series.getPoints() != null && series.getPoints().length > 0) { + updateExistingPointsOfSeriesWithXYPairs(xYPairs, series); + } else { + addXYPairsToSeries(xYPairs, series); + chart.addSeries(series , true, new Animation().setDuration(20000).setEasing(Easing.SWING)); + } + chart.setSizeToMatchContainer(); + } + + private void updateExistingPointsOfSeriesWithXYPairs(List> xYPairs, Series series){ + int counter = 0; + if (series != null) { + for (Point point : series.getPoints()) { + Pair xYPair = xYPairs.get(counter); + point.update(xYPair.getA(), xYPair.getB(), false); + counter++; + } + } + chart.redraw(); + } + + private void addXYPairsToSeries(List> xYPairs, Series series){ + for (Pair xYPair : xYPairs) { + series.addPoint(new Point(xYPair.getA(), xYPair.getB()), true, false, new Animation().setDuration(2000)); + } + } + + + @Override + public void add(Widget w) { + throw new UnsupportedOperationException("The method add(Widget w) is not supported."); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("The method clear() is not supported."); + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public boolean remove(Widget w) { + return false; + } + + private void loadData() { + GetStartlineAdvantagesAction getRibDashboardRaceInfoAction = new GetStartlineAdvantagesAction( + ribDashboardService, leaderboardName); + asyncActionsExecutor.execute(getRibDashboardRaceInfoAction, new AsyncCallback>>() { + + @Override + public void onSuccess(List> result) { + updateSeriesPoints(result); + } + + @Override + public void onFailure(Throwable caught) { + } + }); + } + + @Override + public void timeChanged(Date newTime, Date oldTime) { + loadData(); + } +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml new file mode 100644 index 00000000000..552c1eea384 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css new file mode 100644 index 00000000000..1b2ae9f8633 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css @@ -0,0 +1,19 @@ +@CHARSET "UTF-8"; + +.advantages_on_line_chart_container { + position: absolute !important; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + font-family: 'Open Sans', Arial, Verdana, sans-serif !important; +} + +.advantages_on_line_chart { + position: absolute; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + font-family: 'Open Sans', Arial, Verdana, sans-serif !important; +} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java index 6a988f36ffd..11683393e12 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java @@ -30,6 +30,8 @@ import com.sap.sailing.domain.tracking.TrackedLeg; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.server.RacingEventService; import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; /** @@ -261,4 +263,17 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib return null; } } + + @Override + public List> getAdvantagesOnStartline(String leaderboardName) { + return generateRandomAdvantagesOnStartline(); + } + + private List> generateRandomAdvantagesOnStartline(){ + List> randomAdvantagesOnStartline = new ArrayList>(); + for(int i = 0; i <= 100; i = i+20){ + randomAdvantagesOnStartline.add(new Pair(new Double(i), new Double((i+1)/2+(0 + (int)(Math.random()*5))))); + } + return randomAdvantagesOnStartline; + } } \ No newline at end of file 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 942cb8ec6fd..42a00f668db 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 @@ -1249,12 +1249,19 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c String dashboardNewStartAnalysisAvailable(); - String dashboardStartlineAdvantageByWind(); + String dashboardStartlineAdvantagesByWind(); String dashboardStartlineAdvantageByGeometry(); String dashboardRankAtFirstMark(); String dashboardTeam(); String dashboardDistanceToLineInM(); String dashboardSpeedInKts(); + + String dashboardAdvantageInSeconds(); + String dashboardSecondsAbreviation(); + String dashboardDistanceToRCBoat(); + String dashboardPinEnd(); + String dashboardRCBoat(); + String fixedMarkPassing(); String suppressedMarkPassing(); String windUp(); 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 71501436ce8..4bf80ca03f4 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 @@ -1211,12 +1211,17 @@ dashboardAverageWind=average dashboardAverageWindMinutes=({0} minutes) dashboardWindChartHint=Tap on chart to change interval dashboardNewStartAnalysisAvailable=New start analysis available -dashboardStartlineAdvantageByWind=Startline advantage by wind +dashboardStartlineAdvantagesByWind=Startline advantage by wind dashboardStartlineAdvantageByGeometry=Startline advantage by geometry dashboardRankAtFirstMark=Rank at first mark dashboardTeam=Team dashboardDistanceToLineInM=Distance to line in m dashboardSpeedInKts=Speed in kts +dashboardAdvantageInSeconds = Advantage in Seconds +dashboardSecondsAbreviation = s +dashboardDistanceToRCBoat = Distance to RC Boat +dashboardPinEnd = Pin End +dashboardRCBoat = RC Boat fixedMarkPassing=(fixed) suppressedMarkPassing=(suppressed) windUp=Wind-Up (show wind from top of map) 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 676b8e34404..2eab59770bf 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 @@ -1201,12 +1201,17 @@ dashboardAverageWind=average dashboardAverageWindMinutes=({0} minutes) dashboardWindChartHint=Auf Chart drücken um Interval zu ändern dashboardNewStartAnalysisAvailable=Neue Startanalyse verfügbar -dashboardStartlineAdvantageByWind=Startlininien Vorteil nach Wind +dashboardStartlineAdvantagesByWind=Startlininien Vorteil nach Wind dashboardStartlineAdvantageByGeometry=Startlininien Vorteil nach Geometrie dashboardRankAtFirstMark=Position an erster Bahnmarke dashboardTeam=Team dashboardDistanceToLineInM=Distanz zur Linie in m dashboardSpeedInKts=Geschwindigkeit in kts +dashboardAdvantageInSeconds = "Vorteil in Sekunden" +dashboardSecondsAbreviation = s +dashboardDistanceToRCBoat = "Abstand zum Startboot" +dashboardPinEnd = "Pin End" +dashboardRCBoat = "Startboot" fixedMarkPassing=(fest) suppressedMarkPassing=(unterdrückt) windUp=Wind von oben anzeigen 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 e38f7f943ac..f203c5c85ca 100755 --- 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 @@ -1149,12 +1149,17 @@ dashboardAverageWind=average dashboardAverageWindMinutes=({0} minutes) dashboardWindChartHint=Tap on chart to change interval dashboardNewStartAnalysisAvailable=New start analysis available -dashboardStartlineAdvantageByWind=Startline advantage by wind +dashboardStartlineAdvantagesByWind=Startline advantage by wind dashboardStartlineAdvantageByGeometry=Startline advantage by geometry dashboardRankAtFirstMark=Rank at first mark dashboardTeam=Team dashboardDistanceToLineInM=Distance to line in m dashboardSpeedInKts=Speed in kts +dashboardAdvantageInSeconds = Advantage in Seconds +dashboardSecondsAbreviation = s +dashboardDistanceToRCBoat = Distance to RC Boat +dashboardPinEnd = Pin End +dashboardRCBoat = RC Boat fixedMarkPassing=(fixed) suppressedMarkPassing=(suppressed) windUp=Wind-Up (show wind from top of map) 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 9fd9f948e43..c1656b2bbab 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 @@ -172,6 +172,10 @@ live=live tacks=迎风转向 windSensorWindSourceTypeName=Measured actionOpenDashboard=Open Coach Dashboard +dashboardAdvantageInSeconds = "Advantage in Seconds" +dashboardDistanceToRCBoat = "Distance to RC Boat" +dashboardPinEnd = "Pin End" +dashboardRCBoat = "RC Boat" polarSheetUseOnlyEstimationData=Use only estimation for wind direction showingDetailsOfRace=Showing details for race {0} gapToLeaderInSeconds=与第一名的差距 @@ -1072,7 +1076,8 @@ windwardDistanceToGoInMetersTooltip=迎/顺风航段时参赛队的位置离开 papaDisplayed=Start mode flag - four minutes till start sheetNameTooltip=You can name your polar sheet using the text field.nA name will be generated using the boat classnif no name is provided. competitorsFilter=参赛队过滤 -dashboardStartlineAdvantageByWind=Startline advantage by wind +dashboardStartlineAdvantagesByWind=Startline advantage by wind +dashboardSecondsAbreviation=s pleaseEnterNonEmptyDescription=Please enter a non-empty description polarSheetChart=Polar Sheet histogram=Histogram From f82af2c5ecf6d752a245d098b1a0388506cd3b8c Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Mon, 15 Jun 2015 17:16:45 +0200 Subject: [PATCH 002/167] added two startline advantage widgets and adapted font sizes and spaces --- .../gwt/client/RibDashboardPanel.java | 5 +++++ .../gwt/client/RibDashboardPanel.ui.xml | 10 ++++++---- .../sailing/dashboards/gwt/client/Ribstyle.css | 17 +++++++++++++---- .../client/startanalysis/StartlineAnalysis.css | 2 +- .../startlineadvantage/LiveAverageComponent.css | 6 +++--- .../LiveAverageComponent.ui.xml | 4 ++-- .../StartLineAdvantageComponent.css | 4 ++-- .../StartLineAdvantageComponent.java | 15 +++++++-------- .../StartlineAdvantagesByWindComponent.java | 6 +++++- .../StartlineAdvantagesByWindComponentStyle.css | 1 + .../client/windchart/WindBotComponentStyle.css | 2 +- 11 files changed, 46 insertions(+), 26 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java index 0dc6416b7d3..f6d798e45bd 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.java @@ -24,6 +24,7 @@ import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverP import com.sap.sailing.dashboards.gwt.client.eventlogo.EventLogo; import com.sap.sailing.dashboards.gwt.client.notifications.WrongDeviceOrientationNotification; import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisComponent; +import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartLineAdvantageComponent; import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartlineAdvantagesByWindComponent; import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; @@ -81,6 +82,9 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr @UiField(provided = true) public StartlineAnalysisComponent startanalysisComponent; + + @UiField(provided = true) + public StartLineAdvantageComponent startlineAdvantageByGeometryComponent; private List windBotComponents; private StringMessages stringConstants; @@ -91,6 +95,7 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr ribDashboardDataRetriever.addDataObserver(this); startanalysisComponent = new StartlineAnalysisComponent(ribDashboardService, sailingServiceAsync); startlineAdvantagesByWindComponent = new StartlineAdvantagesByWindComponent(ribDashboardService); + startlineAdvantageByGeometryComponent = new StartLineAdvantageComponent(ribDashboardDataRetriever); stringConstants = StringMessages.INSTANCE; initWidget(uiBinder.createAndBindUi(this)); initLogos(); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml index bbf6cf92eef..50f78da058b 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml @@ -36,12 +36,14 @@ ui:field="startanalysisComponent"> - - - + + + + - +
diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css index d59bc127c64..5ece3690d1b 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css @@ -130,14 +130,23 @@ height: 200%; } -.startlineadvantagepanel { +.startline_advantage_by_wind_container { position: absolute; background-color: white; - top: 0pt; + top: 27%; right: 0pt; left: 0pt; - bottom: 30%; - margin-bottom: 5pt; + bottom: 0%; +} + +.startline_advantage_by_geometry_container { + position: absolute; + background-color: white; + top: 0%; + right: 0pt; + left: 0pt; + bottom: 73%; + margin-bottom: 10pt; } .hintpanel { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysis.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysis.css index 01b8e89e2c3..bb188a8b41b 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysis.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startanalysis/StartlineAnalysis.css @@ -15,7 +15,7 @@ margin-top: 0; line-height: 30pt; vertical-align: middle; - font-size: 15pt; + font-size: 14pt; font-family: 'Open Sans', Arial, Verdana, sans-serif; width: 100%; text-align: center; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css index 7eb53bbd5f2..62094360316 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.css @@ -20,7 +20,7 @@ margin-top: 5pt; line-height: 15pt; vertical-align: middle; - font-size: 12.5pt; + font-size: 13pt; font-family: 'Open Sans', Arial, Verdana, sans-serif; width: 100%; text-align: center; @@ -56,12 +56,12 @@ .liveAverageCompoment_panel_value_number { font-family: 'Open Sans', Arial, Verdana, sans-serif; - font-size: 27pt; + font-size: 26pt; } .liveAverageCompoment_panel_value_unit { font-family: 'Open Sans', Arial, Verdana, sans-serif; - font-size: 11pt; + font-size: 15pt; } .liveAverageCompoment_panel_value_unit_degrees { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.ui.xml index fa77bcce139..49cb75c6be2 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.ui.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.ui.xml @@ -13,7 +13,7 @@
- +
@@ -24,7 +24,7 @@
- +
diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.css index 9ed5e627f4d..93008d74441 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.css @@ -1,12 +1,12 @@ @CHARSET "UTF-8"; .startLineAdvantageComponent_liveAveragePanel { - bottom: 25pt; + bottom: 5pt; margin-top: 4pt; } .startLineAdvantageComponent_header { - font-size: 15pt; + font-size: 14pt; } .startLineAdvantageComponent_livePanel { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java index b0088e19a06..a435d594e75 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java @@ -22,16 +22,15 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements private StartLineAdvantageComponentState startLineAdvantageComponentState; private StartLineAdvantageComponentStateShowsAdvantageByWind startLineAdvantageComponentStateShowsAdvantageByWind; private StartLineAdvantageComponentStateShowsAdvantageByGeometry startLineAdvantageComponentStateShowsAdvantageByGeometry; - private StringMessages stringConstants; + private static StringMessages stringConstants = StringMessages.INSTANCE; public StartLineAdvantageComponent(RibDashboardDataRetriever ribDashboardDataRetriever) { - super(); - stringConstants = StringMessages.INSTANCE; + super(stringConstants.dashboardStartlineAdvantageByGeometry(), "m"); initAndSetStartLineAdvantageStates(); StartLineAdvantageComponentRessources.INSTANCE.css().ensureInjected(); - this.header.setInnerText(stringConstants.dashboardStartlineAdvantagesByWind()); - this.header.addClassName(StartLineAdvantageComponentRessources.INSTANCE.css() - .startLineAdvantageComponent_header()); + this.header.setInnerText(stringConstants.dashboardStartlineAdvantageByGeometry()); + this.header.addClassName(StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_header()); + liveAveragePanel.getElement().addClassName( StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_liveAveragePanel()); livePanel.getElement().addClassName( @@ -41,14 +40,14 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements averagePanel.getElement().addClassName( StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_averagePanel()); this.liveLabel.setInnerHTML(stringConstants.dashboardLiveWind()); - this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"
"+stringConstants.dashboardAverageWindMinutes(60)); + this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"
"+stringConstants.dashboardAverageWindMinutes(15)); ribDashboardDataRetriever.addDataObserver(this); } private void initAndSetStartLineAdvantageStates() { startLineAdvantageComponentStateShowsAdvantageByWind = new StartLineAdvantageComponentStateShowsAdvantageByWind(); startLineAdvantageComponentStateShowsAdvantageByGeometry = new StartLineAdvantageComponentStateShowsAdvantageByGeometry(); - startLineAdvantageComponentState = startLineAdvantageComponentStateShowsAdvantageByWind; + startLineAdvantageComponentState = startLineAdvantageComponentStateShowsAdvantageByGeometry; } @Override diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java index cd6bb5edbc5..7370efe64c3 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java @@ -3,6 +3,7 @@ package com.sap.sailing.dashboards.gwt.client.startlineadvantage; import java.util.Iterator; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; @@ -40,8 +41,11 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has public StartlineAdvantagesByWindComponent(RibDashboardServiceAsync ribDashboardService) { startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart(ribDashboardService); advantageMaximumLiveAverage = new LiveAverageComponent(StringMessages.INSTANCE.dashboardStartlineAdvantagesByWind(), "s"); + advantageMaximumLiveAverage.header.getStyle().setFontSize(14, Unit.PT); + advantageMaximumLiveAverage.liveLabel.setInnerHTML("advantage max."); + advantageMaximumLiveAverage.averageLabel.setInnerHTML("advantage max. average "+StringMessages.INSTANCE.dashboardAverageWindMinutes(15)); initWidget(uiBinder.createAndBindUi(this)); - advantageMaximumLiveAverage.updateValues("55", "43"); + advantageMaximumLiveAverage.updateValues("55.7", "43.9"); } @Override diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css index c1e629ef0df..d6d6da58539 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponentStyle.css @@ -10,6 +10,7 @@ position: absolute; height: 30%; width: 100%; + top: 4pt; } .advantages_on_line_chart_container{ diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponentStyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponentStyle.css index 90bfd8f5188..799c6df9a76 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponentStyle.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponentStyle.css @@ -11,7 +11,7 @@ height: 45pt; line-height: 45pt; vertical-align: middle; - font-size: 15pt; + font-size: 14pt; font-family: 'Open Sans', Arial, Verdana, sans-serif; width: 100%; text-align: center; From ec097a63e764a1826df697cec54c2dd0e438e564 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 26 Jun 2015 21:56:55 +0200 Subject: [PATCH 003/167] started to work on bug 3022, cleaning up the DistanceCache leaking mess --- .../sap/sailing/domain/test/TrackTest.java | 43 +++++++++++++++++++ .../domain/tracking/impl/GPSFixTrackImpl.java | 4 +- .../src/com/sap/sse/common/Duration.java | 1 + .../common/impl/MillisecondsDurationImpl.java | 5 +++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java index 5e2870f4516..f2795b3b304 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java @@ -53,6 +53,7 @@ import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl; import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl; import com.sap.sailing.domain.tracking.impl.MaxSpeedCache; import com.sap.sailing.domain.tracking.impl.TrackImpl; +import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimeRange; import com.sap.sse.common.Timed; @@ -894,6 +895,48 @@ public class TrackTest { assertEquals(toReachInOneThirdOfTimeBetweenFixesInMillis.getMeters(), distance3_new.getMeters()-distance2_new.getMeters(), 0.01); assertEquals(toReachInOneThirdOfTimeBetweenFixesInMillis.getMeters(), distance4_new.getMeters()-distance3_new.getMeters(), 0.01); } + + /** + * Bug 3022 describes a {@link StackOverflowError} that occurs during distance calculations on a {@link GPSFixTrackImpl}. + * This test tries to reproduce this behavior, as a starting point for a fix. The recursion happened while a long-distance + * race was running. Can there be a certain fix insertion pattern that, combined with a certain request pattern, + * produces degenerated cache contents? The race had a live delay of 660s. The trackers were configured to sample every + * 120s and to send every 600s. This could mean that for some 60s the live requests were "ahead" of the trackers. + */ + @Test + public void testDistanceCacheIncrementalFillUpAndRecursion() { + TimePoint start = MillisecondsTimePoint.now(); + TimePoint fixTime = start; + TimePoint queryTime = fixTime; + Position p = new DegreePosition(0, 0); + Bearing cog = new DegreeBearingImpl(123); + final Duration queryInterval = Duration.ONE_SECOND; + final Duration readAhead = Duration.ONE_MINUTE; + final Duration samplingInterval = Duration.ONE_SECOND.times(120); + final Duration transmissionInterval = Duration.ONE_MINUTE.times(10); + final Duration raceDuration = Duration.ONE_HOUR.times(48); + final Speed speed = new KnotSpeedImpl(12); + final Distance distancePerSample = speed.travel(fixTime, fixTime.plus(samplingInterval)); + DynamicGPSFixTrack track = new DynamicGPSFixTrackImpl(new Object(), /* millisecondsOverWhichToAverage */ 30000l); + while (fixTime.before(start.plus(raceDuration))) { + for (int i=0; i= 0); + lastDistance = d; + queryTime = queryTime.plus(queryInterval); + } + } + System.out.println(); + } @Test public void testDistanceCacheAccessForPartialStrip() { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java index 8cf2cc16b9f..cd7ee6a0467 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java @@ -554,7 +554,9 @@ public class GPSFixTrackImpl extends TrackImpl } finally { unlockAfterRead(); } - getDistanceCache().cache(from, to, result); + if (recursionDepth == 0) { + getDistanceCache().cache(from, to, result); + } } return result; } diff --git a/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java b/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java index a874fa524a0..ea0e1de8f35 100755 --- a/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java +++ b/java/com.sap.sse.common/src/com/sap/sse/common/Duration.java @@ -32,6 +32,7 @@ public interface Duration extends Serializable, Comparable { Duration divide(long divisor); Duration divide(double divisor); + double divide(Duration duration); Duration times(long factor); Duration times(double factor); diff --git a/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java b/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java index 817442d27c8..a42de4256a2 100755 --- a/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java +++ b/java/com.sap.sse.common/src/com/sap/sse/common/impl/MillisecondsDurationImpl.java @@ -33,6 +33,11 @@ public class MillisecondsDurationImpl implements Duration { return new MillisecondsDurationImpl((long) (1. / divisor * asMillis())); } + @Override + public double divide(Duration duration) { + return ((double) asMillis()) / (double) duration.asMillis(); + } + @Override public Duration times(long factor) { return new MillisecondsDurationImpl(asMillis() * factor); From 99966882ca9a97e5f577ec99634c32b76234af94 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 26 Jun 2015 22:29:01 +0200 Subject: [PATCH 004/167] bug 3022: using an lru cache based on an access order sorting LinkedHashMap which implements size limitation for DistanceCache --- .../domain/tracking/impl/DistanceCache.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java index a8fdb2a597d..88c4b7ff7e2 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java @@ -2,12 +2,15 @@ package com.sap.sailing.domain.tracking.impl; import java.util.Comparator; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map.Entry; import java.util.NavigableSet; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; +import com.sap.sse.common.Util.Pair; import com.sap.sse.concurrent.LockUtil; import com.sap.sse.concurrent.NamedReentrantReadWriteLock; import com.sap.sse.util.impl.ArrayListNavigableSet; @@ -68,8 +71,30 @@ import com.sap.sse.util.impl.ArrayListNavigableSet; * @author Axel Uhl (D043530) */ public class DistanceCache { + private static final int MAX_SIZE = 100; + private final NavigableSet>>> distanceCache; + /** + * The cache is to have limited size. Eviction shall happen based on a least-recently-used strategy. Usage is + * defined as having been returned by {@link #getEarliestFromAndDistanceAtOrAfterFrom(TimePoint, TimePoint)} or + * having been added by {@link #cache(TimePoint, TimePoint, Distance)}. + *

+ * + * When an eldest entry is asked to be expunged from this map and the map has more than {@link #MAX_SIZE} elements, + * the expunging will be admitted, and the entry is removed from the {@link #distanceCache} core structure. Reading + * and writing this structure must happen under the {@link #lock write lock} because also reading the linked hash + * map that counts access as "use" has a modifying effect on its internal structures. + *

+ * + * The key pairs are from/to pairs. Note that this is in some sense "the opposite direction" compared to the + * alignment of the {@link #distanceCache} structure which has as its outer keys the "to" time point.

+ * + * Read access is to be synchronized using this field's mutex; write access only happens under the + * {@link #lock write lock} and therefore will have no contenders. + */ + private final LinkedHashMap, Void> lruCache; + private final NamedReentrantReadWriteLock lock; private static final Comparator> timePointInPairComparator = new Comparator>() { @@ -82,6 +107,33 @@ public class DistanceCache { public DistanceCache(String nameForLockLogging) { lock = new NamedReentrantReadWriteLock("lock for DistanceCache for "+nameForLockLogging, /* fair */ true); this.distanceCache = new ArrayListNavigableSet>>>(timePointInPairComparator); + this.lruCache = new LinkedHashMap, Void>(/* initial capacity */ 10, /* load factor */ 0.75f, + /* access-based ordering */ true) { + private static final long serialVersionUID = -6568235517111733193L; + + @Override + protected boolean removeEldestEntry(Entry, Void> eldest) { + final boolean expunge = size() > MAX_SIZE; + if (expunge) { + removeCacheEntry(eldest.getKey().getA(), eldest.getKey().getB()); + } + return expunge; + } + }; + } + + private void removeCacheEntry(TimePoint from, TimePoint to) { + assert lock.getWriteHoldCount() == 1; // we can be sure we are alone here; this only happens when adding a new entry, holding the write lock + Util.Pair>> entryForTo = distanceCache.floor(createDummy(to)); + if (entryForTo.getA().equals(to)) { + Pair entryForFrom = entryForTo.getB().ceiling(new Util.Pair(from, null)); + if (entryForFrom.getA().equals(from)) { + entryForTo.getB().remove(entryForFrom); + if (entryForTo.getB().isEmpty()) { + distanceCache.remove(entryForTo); + } + } + } } /** @@ -101,6 +153,12 @@ public class DistanceCache { result = new Util.Pair>(entryForTo.getA(), fromCeiling); } } + // no writer can be active because we're holding the read lock; read access on the lruCache is synchronized using + // the lruCache's mutex; this is necessary because we're using access-based LRU pinging where even getting an entry + // modifies the internal parts of the data structure which is not thread safe. + synchronized (lruCache) { + lruCache.get(new Util.Pair(from, to)); + } return result; } finally { LockUtil.unlockAfterRead(lock); @@ -146,6 +204,7 @@ public class DistanceCache { distanceCache.add(pairForTo); } entryForTo.add(new Util.Pair(from, distance)); + lruCache.put(new Util.Pair(from, to), null); } finally { LockUtil.unlockAfterWrite(lock); } From 6ccd510c79d9325a8ae1ce55ade33a3621a9a22e Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 26 Jun 2015 22:43:20 +0200 Subject: [PATCH 005/167] remove entries from the lruCache structure when they are removed from the distanceCache structure by invalidation --- .../com/sap/sailing/domain/tracking/impl/DistanceCache.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java index 88c4b7ff7e2..59506ef3618 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DistanceCache.java @@ -176,6 +176,9 @@ public class DistanceCache { for (Iterator>>> i=toRemove.iterator(); i.hasNext(); ) { Util.Pair>> entryToRemove = i.next(); assert entryToRemove.getA().compareTo(timePoint) >= 0; + for (Pair fromAndDistance : entryToRemove.getB()) { + lruCache.remove(new Util.Pair<>(fromAndDistance.getA(), entryToRemove.getA())); + } i.remove(); } } finally { From 5fd68c922c5cbbf15b2e977e2886bc2b51abc675 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 26 Jun 2015 23:22:34 +0200 Subject: [PATCH 006/167] added a test case that checks DistanceCache size limitation --- .../src/com/sap/sailing/domain/test/TrackTest.java | 11 +++++++++-- .../sailing/domain/tracking/impl/DistanceCache.java | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java index f2795b3b304..5383a2d6687 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java @@ -917,7 +917,14 @@ public class TrackTest { final Duration raceDuration = Duration.ONE_HOUR.times(48); final Speed speed = new KnotSpeedImpl(12); final Distance distancePerSample = speed.travel(fixTime, fixTime.plus(samplingInterval)); - DynamicGPSFixTrack track = new DynamicGPSFixTrackImpl(new Object(), /* millisecondsOverWhichToAverage */ 30000l); + final DistanceCache distanceCache = new DistanceCache("test-DistanceCache"); + DynamicGPSFixTrack track = new DynamicGPSFixTrackImpl(new Object(), /* millisecondsOverWhichToAverage */ 30000l) { + private static final long serialVersionUID = -7277196393160609503L; + @Override + protected DistanceCache getDistanceCache() { + return distanceCache; + } + }; while (fixTime.before(start.plus(raceDuration))) { for (int i=0; i>>> distanceCache; @@ -122,6 +122,10 @@ public class DistanceCache { }; } + public int size() { + return lruCache.size(); + } + private void removeCacheEntry(TimePoint from, TimePoint to) { assert lock.getWriteHoldCount() == 1; // we can be sure we are alone here; this only happens when adding a new entry, holding the write lock Util.Pair>> entryForTo = distanceCache.floor(createDummy(to)); From 93ae71f78cdb460f24babc649bac99f0affb64a3 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Mon, 13 Jul 2015 15:07:13 +0200 Subject: [PATCH 007/167] added LiveTrackedRaceListener --- .../gwt/server/LiveTrackedRaceListener.java | 15 +++ .../gwt/server/LiveTrackedRaceProvider.java | 29 +++++ .../gwt/server/RibDashboardServiceImpl.java | 7 +- .../StartlineAdvantagesCalculator.java | 116 ++++++++++++++++++ 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceListener.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceProvider.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceListener.java new file mode 100644 index 00000000000..c67872c5d89 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceListener.java @@ -0,0 +1,15 @@ +package com.sap.sailing.dashboards.gwt.server; + +import com.sap.sailing.domain.tracking.TrackedRace; + +/** + * Informs the listener about changes in a certain environment, where a {@link TrackedRace} with + * {@link TrackedRace#getStatus()} live is continuously required. + * + * @author Alexander Ries (D062114) + * + */ +public interface LiveTrackedRaceListener { + + public void liveTrackedRaceDidChange(TrackedRace trackedRace); +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceProvider.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceProvider.java new file mode 100644 index 00000000000..71dc43a4589 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/LiveTrackedRaceProvider.java @@ -0,0 +1,29 @@ +package com.sap.sailing.dashboards.gwt.server; + +import java.util.ArrayList; +import java.util.List; + +import com.sap.sailing.domain.tracking.TrackedRace; + +/** + * Is continuously looking for {@link TrackedRace} with {@link TrackedRace#getStatus()} live and + * notifies {@link LiveTrackedRaceListener} if the current live {@link TrackedRace} has changed. + * + * + * @author Alexander Ries (D062114) + * + */ +public interface LiveTrackedRaceProvider { + + List listener = new ArrayList(); + + public void notifyLiveTrackedRaceListenerAboutLiveTrackedRaceChange(TrackedRace trackedRace); + + default void addLiveTrackedRaceListener(LiveTrackedRaceListener liveTrackedRaceListener){ + listener.add(liveTrackedRaceListener); + } + + default void removeLiveTrackedRaceListener(LiveTrackedRaceListener liveTrackedRaceListener){ + listener.remove(liveTrackedRaceListener); + } +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java index c47ac199355..b2ed2e1facb 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java @@ -41,7 +41,7 @@ import com.sap.sse.common.impl.MillisecondsTimePoint; * @author Alexander Ries (D062114) * */ -public class RibDashboardServiceImpl extends RemoteServiceServlet implements RibDashboardService { +public class RibDashboardServiceImpl extends RemoteServiceServlet implements RibDashboardService, LiveTrackedRaceProvider { /** * @@ -284,4 +284,9 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib } return randomAdvantagesOnStartline; } + + @Override + public void notifyLiveTrackedRaceListenerAboutLiveTrackedRaceChange(TrackedRace trackedRace) { + listener.forEach(listener -> listener.liveTrackedRaceDidChange(trackedRace)); + } } \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java new file mode 100644 index 00000000000..aa1a6d33a6b --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java @@ -0,0 +1,116 @@ +package com.sap.sailing.dashboards.gwt.server.startlineadvantages; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.sap.sailing.dashboards.gwt.server.LiveTrackedRaceListener; +import com.sap.sailing.dashboards.gwt.server.RibDashboardServiceImpl; +import com.sap.sailing.domain.base.Course; +import com.sap.sailing.domain.base.Mark; +import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.tracking.GPSFix; +import com.sap.sailing.domain.tracking.GPSFixTrack; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util.Pair; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +/** + * @author Alexander Ries (D062114) + * + */ +public class StartlineAdvantagesCalculator implements LiveTrackedRaceListener{ + + private TrackedRace currentLiveTrackedRace; + private Pair startlineMarkPositions; + private Position firstMarkPosition; + + private static final Logger logger = Logger.getLogger(StartlineAdvantagesCalculator.class.getName()); + + public StartlineAdvantagesCalculator(){ + } + + public Map getStartLineAdvantagesAccrossLine(){ + Map result = new HashMap(); + // Get Course Buoys + // Get Wind + // Get Maneuver Angle and Boat Speed at Angle + // Calculate intersection point(s) between start line and lay lines + // Get Positions on start line with normal upwind and overlaying lay line upwind + // Calculate duration from start line to first mark for overlaying positions + // Calculate intersection points from normal upwind start positions to first mark + // Calculate duration from two new distances for normal upwind starts + // Put all durations in one set + // Get the smallest of the durations and subtract number from every other number + retrieveFirstLegWayPoints(); + logger.log(Level.INFO, "Startline Startboat : "+startlineMarkPositions.getA()); + logger.log(Level.INFO, "Startline PinEnd: "+startlineMarkPositions.getB()); + logger.log(Level.INFO, "Firstmark: "+firstMarkPosition); + return result; + } + + private void retrieveFirstLegWayPoints() { + if (currentLiveTrackedRace != null) { + Course course = currentLiveTrackedRace.getRace().getCourse(); + if (course != null) { + Waypoint startlineWayPoint= course.getFirstLeg().getFrom(); + Waypoint firstmarkWayPoint = course.getFirstLeg().getTo(); + if (startlineWayPoint != null && firstmarkWayPoint != null) { + retrieveStartlineMarkPositionsFromStartLineWayPoint(startlineWayPoint); + retrieveFirstMarkPositionFromFirstMarkWayPoint(firstmarkWayPoint); + } + } + } + } + + private void retrieveStartlineMarkPositionsFromStartLineWayPoint(Waypoint startLineWayPoint){ + if(startLineWayPoint.getMarks().iterator().hasNext()){ + Mark startboat = startLineWayPoint.getMarks().iterator().next(); + if(startLineWayPoint.getMarks().iterator().hasNext()){ + Mark pinEnd = startLineWayPoint.getMarks().iterator().next(); + TimePoint now = MillisecondsTimePoint.now(); + Position startBoatPosition = getPositionFromMarkAtTimePoint(currentLiveTrackedRace, startboat, now); + Position pinEndPosition = getPositionFromMarkAtTimePoint(currentLiveTrackedRace, pinEnd, now); + startlineMarkPositions = new Pair(startBoatPosition, pinEndPosition); + } + } + } + + private void retrieveFirstMarkPositionFromFirstMarkWayPoint(Waypoint firstMarkWayPoint) { + if (firstMarkWayPoint.getMarks().iterator().hasNext()) { + Mark firstMark = firstMarkWayPoint.getMarks().iterator().next(); + TimePoint now = MillisecondsTimePoint.now(); + firstMarkPosition = getPositionFromMarkAtTimePoint(currentLiveTrackedRace, firstMark, now); + } + } + + private Position getPositionFromMarkAtTimePoint(TrackedRace trackedRace, Mark mark, TimePoint timePoint){ + GPSFixTrack fixTrack = trackedRace.getTrack(mark); + return fixTrack.getEstimatedPosition(timePoint, true); + } + + private void getStartlineOfRace(){ + + } + + private void getFirstMarkOfRace(){ + + } + + private Set getPositionsLineWithStepWidthInMeter(Object line, int meter){ + return null; + } + + private Position getIntersectionPointOfTwoGPSLines(Object line1, Object line2){ + return null; + } + + @Override + public void liveTrackedRaceDidChange(TrackedRace trackedRace) { + this.currentLiveTrackedRace = trackedRace; + } +} From 947ba07204017788faafa04d3b10536b036763ec Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Tue, 14 Jul 2015 10:10:13 +0200 Subject: [PATCH 008/167] addded distanceToRCBoatInMeters to StartLineAdvantageDTO --- .../dashboards/gwt/shared/dto/StartLineAdvantageDTO.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java index 617cf7b2ea9..96965b47b59 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java @@ -1,16 +1,14 @@ package com.sap.sailing.dashboards.gwt.shared.dto; -import java.io.Serializable; - +import com.google.gwt.user.client.rpc.IsSerializable; import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAdvantageType; -public class StartLineAdvantageDTO implements Serializable{ - - private static final long serialVersionUID = 502350559068890424L; +public class StartLineAdvantageDTO implements IsSerializable { public StartlineAdvantageType startLineAdvatageType; public double startLineAdvantage; public double startlineAdvantageAverage; + public double distanceToRCBoatInMeters; public StartLineAdvantageDTO(){} } From ce09b3f4a95165b73e1ad53cb5f56e15df373ae9 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Tue, 14 Jul 2015 15:39:30 +0200 Subject: [PATCH 009/167] added color theme --- .../gwt/client/resources/Colors.java | 15 +++++++++++++++ .../client/resources/DashboardResources.java | 18 ++++++++++++++++++ .../gwt/client/{ => resources}/Ribstyle.css | 0 .../dashboards/gwt/client/resources/colors.gss | 7 +++++++ 4 files changed, 40 insertions(+) create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Colors.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java rename java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/{ => resources}/Ribstyle.css (100%) create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/colors.gss diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Colors.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Colors.java new file mode 100644 index 00000000000..d6fa0e42285 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Colors.java @@ -0,0 +1,15 @@ +package com.sap.sailing.dashboards.gwt.client.resources; + +/** + * @author Alexander Ries (D062114) + * + */ +public class Colors { + /* -> App colors -- */ + public static final String C_PRIMARY = "#000000"; + public static final String C_SECONDARY = "#000000"; + /* -> Default colors -- */ + public static final String C_BACKGROUND = "#000000"; + public static final String C_TEXT = "#000000"; + public static final String C_TEXT_LIGHT = "#000000"; +} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java new file mode 100644 index 00000000000..e85e8032005 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java @@ -0,0 +1,18 @@ +package com.sap.sailing.dashboards.gwt.client.resources; + +/** + * @author Alexander Ries (D062114) + * + */ +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.CssResource; + +public interface DashboardResources extends ClientBundle { + + interface Style extends CssResource { + // Your classes here + } + // We only need to source the theme file + @Source({"colors.gss", "Ribstyle.css"}) + Style style(); +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Ribstyle.css similarity index 100% rename from java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/Ribstyle.css rename to java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Ribstyle.css diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/colors.gss b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/colors.gss new file mode 100644 index 00000000000..e279b9c801c --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/colors.gss @@ -0,0 +1,7 @@ +@provide 'colors'; + +@def C_PRIMARY eval("com.company.project.client.resources.Colors.C_PRIMARY"); +@def C_SECONDARY eval("com.company.project.client.resources.Colors.C_SECONDARY"); +@def C_BACKGROUND eval("com.company.project.client.resources.Colors.C_BACKGROUND"); +@def C_TEXT eval("com.company.project.client.resources.Colors.C_TEXT"); +@def C_TEXT_LIGHT eval("com.company.project.client.resources.Colors.C_TEXT_LIGHT"); \ No newline at end of file From 978102e586314fe3a2aa8020cee0020955058754 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Tue, 14 Jul 2015 15:40:41 +0200 Subject: [PATCH 010/167] added require color to Ribstyle.css --- .../gwt/client/resources/Ribstyle.css | 39 ++----------------- 1 file changed, 3 insertions(+), 36 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Ribstyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Ribstyle.css index 5ece3690d1b..33cb76ab06a 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Ribstyle.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/Ribstyle.css @@ -1,3 +1,4 @@ +@require "colors"; .bar { height: 100%; @@ -16,7 +17,7 @@ position: absolute; border: none; border-radius: 0; - background-color: #d4d4d4; + background-color: C_PRIMARY; left: 0; right: 0; top: 0; @@ -60,40 +61,6 @@ right: 0pt; } -/*??????*/ -.panelHeader { - height: 100%; - line-height: 25pt; - vertical-align: middle; - font-size: 15pt; - font-family: 'Open Sans', Arial, Verdana, sans-serif; - width: 100%; - text-align: center; - font-weight: bold; - overflow: visible; - background-color: white; -} - -/*?????????*/ -.currentaveragepanel { - position: absolute; - border: none; - border-radius: 0pt; - background-color: white; - top: 20pt; - bottom: 75%; -} - -/*????????*/ -.windchartpanel { - position: absolute; - border: none; - border-radius: 0pt; - background-color: white; - top: 25%; - bottom: 0pt; -} - .left { left: 0pt; right: 50%; @@ -125,7 +92,7 @@ } .rootpanel { - background-color: #fafafa; + background-color: C_PRIMARY; width: 100%; height: 200%; } From b58e86d8d728a5f063c5216e2efcbf31b878d9f6 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 10:03:54 +0200 Subject: [PATCH 011/167] added confidence bar to startlineadvantageschart --- .../gwt/client/RibDashboardPanel.ui.xml | 3 +- .../gwt/client/RibDashboardService.java | 4 +- .../gwt/client/RibDashboardServiceAsync.java | 4 +- .../actions/GetStartlineAdvantagesAction.java | 9 +- .../client/resources/DashboardResources.java | 1 + .../LiveAverageComponent.java | 2 +- .../StartlineAdvantagesByWindComponent.java | 51 ++++++- .../StartlineAdvantagesOnLineChart.java | 135 ++++++++++-------- .../StartlineAdvantagesOnLineChart.ui.xml | 11 +- .../StartlineAdvantagesOnLineChartStyle.css | 54 ++++++- .../client/windchart/WindBotComponent.java | 4 +- .../gwt/server/RibDashboardServiceImpl.java | 24 +++- .../StartlineAdvantagesCalculator.java | 1 - .../StartlineAdvantageCalculationBasis.java | 18 +++ .../gwt/shared/dto/StartLineAdvantageDTO.java | 3 +- 15 files changed, 234 insertions(+), 90 deletions(-) create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/StartlineAdvantageCalculationBasis.java diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml index 50f78da058b..3e1122c95cf 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardPanel.ui.xml @@ -7,8 +7,7 @@ xmlns:mgwtpanel="urn:import:com.googlecode.mgwt.ui.client.widget.panel"> + type='com.sap.sailing.dashboards.gwt.client.RibDashboardPanelStyle' src='resources/Ribstyle.css'> diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java index 9632463f7ce..e2cdae773d3 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java @@ -4,10 +4,10 @@ import java.util.List; import com.google.gwt.user.client.rpc.RemoteService; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; +import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.dto.CompetitorDTO; -import com.sap.sse.common.Util.Pair; public interface RibDashboardService extends RemoteService { RibDashboardRaceInfoDTO getLiveRaceInfo(String leaderboardName) throws NoWindException; @@ -16,5 +16,5 @@ public interface RibDashboardService extends RemoteService { List getCompetitorsInLeaderboard(String leaderboardName); - List> getAdvantagesOnStartline(String leaderboardName); + List getAdvantagesOnStartline(String leaderboardName); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java index 14f5e7d8c1a..6c67d39b9d1 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java @@ -4,9 +4,9 @@ import java.util.List; import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; +import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; -import com.sap.sse.common.Util.Pair; public interface RibDashboardServiceAsync { @@ -16,5 +16,5 @@ public interface RibDashboardServiceAsync { void getCompetitorsInLeaderboard(String leaderboardName, AsyncCallback> callback); - void getAdvantagesOnStartline(String leaderboardName, AsyncCallback>> callback); + void getAdvantagesOnStartline(String leaderboardName, AsyncCallback> callback); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java index 112b76cd824..dc237513d0b 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java @@ -9,10 +9,10 @@ import java.util.List; import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; -import com.sap.sse.common.Util.Pair; +import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; import com.sap.sse.gwt.client.async.AsyncAction; -public class GetStartlineAdvantagesAction implements AsyncAction>> { +public class GetStartlineAdvantagesAction implements AsyncAction> { private final RibDashboardServiceAsync ribDashboardService; private final String leaderboardName; @@ -23,7 +23,6 @@ public class GetStartlineAdvantagesAction implements AsyncAction>> callback) { + public void execute(AsyncCallback> callback) { ribDashboardService.getAdvantagesOnStartline(leaderboardName, callback); - } -} \ No newline at end of file + }} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java index e85e8032005..fb1a18942ff 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/resources/DashboardResources.java @@ -12,6 +12,7 @@ public interface DashboardResources extends ClientBundle { interface Style extends CssResource { // Your classes here } + // We only need to source the theme file @Source({"colors.gss", "Ribstyle.css"}) Style style(); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java index 4628cf14334..0f84b6882c9 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java @@ -100,7 +100,7 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"
"+stringConstants.dashboardAverageWindMinutes(15)); } - public void updateValues(String liveValue, String averageValue) { + public void setValues(String liveValue, String averageValue) { this.liveNumber.setInnerText(liveValue); this.averageNumber.setInnerText(averageValue); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java index 7370efe64c3..4c6071d688e 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java @@ -1,23 +1,32 @@ package com.sap.sailing.dashboards.gwt.client.startlineadvantage; +import java.util.Date; import java.util.Iterator; +import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; +import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesAction; +import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.gwt.client.async.AsyncActionsExecutor; +import com.sap.sse.gwt.client.player.TimeListener; +import com.sap.sse.gwt.client.player.Timer; +import com.sap.sse.gwt.client.player.Timer.PlayModes; /** * @author Alexander Ries (D062114) * */ -public class StartlineAdvantagesByWindComponent extends Composite implements HasWidgets { +public class StartlineAdvantagesByWindComponent extends Composite implements HasWidgets, TimeListener { private static StartlineAdvantagesByWindComponentUiBinder uiBinder = GWT .create(StartlineAdvantagesByWindComponentUiBinder.class); @@ -38,14 +47,45 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has @UiField StartlineAdvantagesByWindComponentStyle style; + private RibDashboardServiceAsync ribDashboardService; + private AsyncActionsExecutor asyncActionsExecutor; + private String leaderboardName; + public StartlineAdvantagesByWindComponent(RibDashboardServiceAsync ribDashboardService) { - startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart(ribDashboardService); + startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart(); advantageMaximumLiveAverage = new LiveAverageComponent(StringMessages.INSTANCE.dashboardStartlineAdvantagesByWind(), "s"); advantageMaximumLiveAverage.header.getStyle().setFontSize(14, Unit.PT); advantageMaximumLiveAverage.liveLabel.setInnerHTML("advantage max."); advantageMaximumLiveAverage.averageLabel.setInnerHTML("advantage max. average "+StringMessages.INSTANCE.dashboardAverageWindMinutes(15)); initWidget(uiBinder.createAndBindUi(this)); - advantageMaximumLiveAverage.updateValues("55.7", "43.9"); + this.ribDashboardService = ribDashboardService; + this.asyncActionsExecutor = new AsyncActionsExecutor(); + initSampleTimer(); + } + + private void loadData() { + GetStartlineAdvantagesAction getRibDashboardRaceInfoAction = new GetStartlineAdvantagesAction( + ribDashboardService, ""); + asyncActionsExecutor.execute(getRibDashboardRaceInfoAction, new AsyncCallback>() { + + @Override + public void onFailure(Throwable caught) { + } + + @Override + public void onSuccess(List result) { + startlineAdvantagesOnLineChart.setStartlineAdvantages(result); + advantageMaximumLiveAverage.setValues("44.2", "23.1"); + } + + }); + } + + private void initSampleTimer(){ + Timer timer = new Timer(PlayModes.Live); + timer.setRefreshInterval(3000); + timer.addTimeListener(this); + timer.play(); } @Override @@ -67,4 +107,9 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has public boolean remove(Widget w) { return false; } + + @Override + public void timeChanged(Date newTime, Date oldTime) { + loadData(); + } } \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java index 2334a3b4fa4..139940ee60d 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java @@ -8,6 +8,7 @@ import org.moxieapps.gwt.highcharts.client.Animation; import org.moxieapps.gwt.highcharts.client.Animation.Easing; import org.moxieapps.gwt.highcharts.client.AxisTitle; import org.moxieapps.gwt.highcharts.client.Chart; +import org.moxieapps.gwt.highcharts.client.Color; import org.moxieapps.gwt.highcharts.client.Credits; import org.moxieapps.gwt.highcharts.client.Legend; import org.moxieapps.gwt.highcharts.client.PlotLine.DashStyle; @@ -23,6 +24,7 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.AreaPlotOptions; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.DivElement; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; @@ -34,6 +36,7 @@ import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesAction; +import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sse.common.Util.Pair; import com.sap.sse.gwt.client.async.AsyncActionsExecutor; @@ -45,7 +48,7 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes; * @author Alexander Ries (D062114) * */ -public class StartlineAdvantagesOnLineChart extends Composite implements HasWidgets, TimeListener { +public class StartlineAdvantagesOnLineChart extends Composite implements HasWidgets { private static StartlineAdvantagesOnLineChartUiBinder uiBinder = GWT.create(StartlineAdvantagesOnLineChartUiBinder.class); @@ -57,44 +60,43 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg @UiField HTMLPanel chartContainer; + + @UiField + DivElement confidenceBarHeader; + + @UiField + DivElement confidenceBarMinLabel; + + @UiField + DivElement confidenceBarMaxLabel; - private RibDashboardServiceAsync ribDashboardService; - private AsyncActionsExecutor asyncActionsExecutor; - private String leaderboardName; private Chart chart; private Series series; - private static final String PARAM_LEADERBOARD_NAME = "leaderboardName"; + private static final int POINT_ADDING_ANIMATION_DURATION_IN_MILLIS = 2000; - public StartlineAdvantagesOnLineChart(RibDashboardServiceAsync ribDashboardService) { - this.ribDashboardService = ribDashboardService; - this.asyncActionsExecutor = new AsyncActionsExecutor(); - this.leaderboardName = Window.Location.getParameter(PARAM_LEADERBOARD_NAME); + public StartlineAdvantagesOnLineChart() { initWidget(uiBinder.createAndBindUi(this)); initAndAddChart(); - + setConfidenceColorBarLabelValues(); //TODO Remove and centralize data retrieving - initSampleTimer(); - } - - private void initSampleTimer(){ - Timer timer = new Timer(PlayModes.Live); - timer.setRefreshInterval(3000); - timer.addTimeListener(this); - timer.play(); } private void initAndAddChart() { chart = initChart(); + /** + * Highcharts default chart element spacing is not consistent + * so there is a need to correct the right spacing + * of the chart to make it look visually right. + * */ setCorrectChartSpacing(chart); setXAxisOfChart(chart); setYAxisOfChart(chart); series = createSeries(chart); - chart.addSeries(createSeries(chart)); chartContainer.add(chart); } - private Chart initChart(){ + private Chart initChart() { Chart chart = new Chart() .setType(Series.Type.AREA) .setChartTitleText(null) @@ -108,11 +110,6 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg return chart; } - /** - * Highcharts default chart element spacing is not consistent - * so there is a need to correct the right spacing - * of the chart to make it look visually right. - * */ private void setCorrectChartSpacing(Chart chart){ chart.setSpacingTop(17) .setSpacingBottom(13) @@ -162,10 +159,16 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg .setPlotOptions( new AreaPlotOptions().setDashStyle(DashStyle.SOLID).setLineWidth(1) .setMarker(new Marker().setEnabled(false)).setShadow(false).setHoverStateEnabled(false) - .setLineColor("#008FFF").setFillColor("#008FFF")); + .setLineColor("#FFFFFF").setFillColor("#FFFFFF")); return series; } + private void setConfidenceColorBarLabelValues() { + confidenceBarHeader.setInnerText("CONFIDENCE"); + confidenceBarMaxLabel.setInnerText("High"); + confidenceBarMinLabel.setInnerText("Low"); + } + private String getAxisLabelValueForLabelData(double labelData) { String result = String.valueOf(labelData); com.sap.sse.common.Util.Pair firstAndLastXValue = getFirstnAndLastXValueOfSeries(); @@ -192,37 +195,44 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg } } - /** - * Removed all Points and adds new ones - * */ - private void updateSeriesPoints(List> xYPairs) { + public void setStartlineAdvantages(List startlineAdvantages) { if (series.getPoints() != null && series.getPoints().length > 0) { - updateExistingPointsOfSeriesWithXYPairs(xYPairs, series); + updateStartlineAdvantages(startlineAdvantages, series); } else { - addXYPairsToSeries(xYPairs, series); - chart.addSeries(series , true, new Animation().setDuration(20000).setEasing(Easing.SWING)); + addStartlineAdvantages(startlineAdvantages, series); } chart.setSizeToMatchContainer(); } - private void updateExistingPointsOfSeriesWithXYPairs(List> xYPairs, Series series){ + private void updateStartlineAdvantages(List startlineAdvantages, Series series) { int counter = 0; if (series != null) { for (Point point : series.getPoints()) { - Pair xYPair = xYPairs.get(counter); - point.update(xYPair.getA(), xYPair.getB(), false); + StartLineAdvantageDTO currentNewStartlineAdvantage = startlineAdvantages.get(counter); + point.update(currentNewStartlineAdvantage.distanceToRCBoatInMeters, currentNewStartlineAdvantage.startLineAdvantage, false); counter++; } } chart.redraw(); } - private void addXYPairsToSeries(List> xYPairs, Series series){ - for (Pair xYPair : xYPairs) { - series.addPoint(new Point(xYPair.getA(), xYPair.getB()), true, false, new Animation().setDuration(2000)); + private void addStartlineAdvantages(List startlineAdvantages, Series series){ + //TODO Build this with forEach Consumer as soon as the bundle uses GWT 2.8 with Java 8 Support. + for (StartLineAdvantageDTO startlineAdvantage : startlineAdvantages) { + Point point = new Point(startlineAdvantage.distanceToRCBoatInMeters, startlineAdvantage.startLineAdvantage); + series.addPoint(point, true, false, new Animation().setDuration(POINT_ADDING_ANIMATION_DURATION_IN_MILLIS)); } + setConfidenceGradientColorToSeries(series, startlineAdvantages); + chart.addSeries(series , true, new Animation().setDuration(POINT_ADDING_ANIMATION_DURATION_IN_MILLIS).setEasing(Easing.SWING)); + } + + private void setConfidenceGradientColorToSeries(Series series, List startlineAdvantages) { + Color confidenceGradientColor = ConfidenceColorCalculator.getColorWithConfidenceGradients(startlineAdvantages); + series.setPlotOptions( + new AreaPlotOptions().setDashStyle(DashStyle.SOLID).setLineWidth(1) + .setMarker(new Marker().setEnabled(false)).setShadow(false).setHoverStateEnabled(false) + .setLineColor("#FFFFFF").setFillColor(confidenceGradientColor)); } - @Override public void add(Widget w) { @@ -244,24 +254,35 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg return false; } - private void loadData() { - GetStartlineAdvantagesAction getRibDashboardRaceInfoAction = new GetStartlineAdvantagesAction( - ribDashboardService, leaderboardName); - asyncActionsExecutor.execute(getRibDashboardRaceInfoAction, new AsyncCallback>>() { - - @Override - public void onSuccess(List> result) { - updateSeriesPoints(result); + private static class ConfidenceColorCalculator { + private static final String LOW_CONFIDENCE_COLOR_AS_HEX = "#43cea2"; + private static final String HIGHT_CONFIDENCE_COLOR_AS_HEX = "#008FFF"; + + public static Color getColorWithConfidenceGradients(List startlineAdvantages) { + Color color = new Color().setLinearGradient(1.0, 0.0, 0.0, 0.0); + double lineLenght = getBiggestDistanceToRCBoat(startlineAdvantages); + for(StartLineAdvantageDTO startlineAdvantageDTO : startlineAdvantages) { + double gradientPosition = getGradientStopPositionFromStartlineLenghtAndDistanceToRCBoat(lineLenght, startlineAdvantageDTO.distanceToRCBoatInMeters); + color.addColorStop(gradientPosition, getColorAsHexStringFromConfidence(startlineAdvantageDTO.confidence)); } - - @Override - public void onFailure(Throwable caught) { + return color; + } + + private static double getGradientStopPositionFromStartlineLenghtAndDistanceToRCBoat(double startlineLenght, double distanceToRCBoat) { + return distanceToRCBoat/startlineLenght; + } + + private static String getColorAsHexStringFromConfidence(double position) { + if(position >= 0.5) { + return HIGHT_CONFIDENCE_COLOR_AS_HEX; + }else { + return LOW_CONFIDENCE_COLOR_AS_HEX; } - }); - } - - @Override - public void timeChanged(Date newTime, Date oldTime) { - loadData(); + } + + private static double getBiggestDistanceToRCBoat(List startlineAdvantages) { + StartLineAdvantageDTO startlineAdvantageDTO = startlineAdvantages.get(startlineAdvantages.size()-1); + return startlineAdvantageDTO.distanceToRCBoatInMeters; + } } } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml index 552c1eea384..4ad17a938af 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.ui.xml @@ -5,7 +5,14 @@ - - + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css index 1b2ae9f8633..61d5a36e27d 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChartStyle.css @@ -3,17 +3,61 @@ .advantages_on_line_chart_container { position: absolute !important; top: 0px; - bottom: 0px; + bottom: 50px; left: 0px; right: 0px; font-family: 'Open Sans', Arial, Verdana, sans-serif !important; } -.advantages_on_line_chart { +.confidence_bar_container { + position: absolute; + height: 50px; + width: 100%; + bottom: 0px; + background-color: white; +} + +.confidence_bar{ position: absolute; top: 0px; - bottom: 0px; - left: 0px; - right: 0px; + left: 15px; + right: 15px; + height: 15px; + background: -moz-linear-gradient(left, #43cea2 0%, #008FFF 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left bottom, right bottom, color-stop(0%,#43cea2), color-stop(100%,#008FFF)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(left, #43cea2 0%,#008FFF 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(left, #43cea2 0%,#008FFF 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(left, #43cea2 0%,#008FFF 100%); /* IE10+ */ + background: linear-gradient(to right, #43cea2 0%,#008FFF 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#43cea2', endColorstr='#008FFF',GradientType=0 ); /* IE6*/ +} + +.confidence_bar_header{ + position: absolute; + top: 0px; + left: 15px; + right: 15px; + height: 15px; + color: white; + font-size: 11px; + text-align: center; + vertical-align: center; font-family: 'Open Sans', Arial, Verdana, sans-serif !important; +} + +.confidence_bar_label { + position: absolute; + top: 20px; + font-size: 12px; + color: grey; + font-family: 'Open Sans', Arial, Verdana, sans-serif !important; +} + +.confidence_bar_min_label { + left: 15px; +} + +.confidence_bar_max_label { + right: 15px; + text-align: right; } \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java index bd00160790c..ffd1c4dac49 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java @@ -174,12 +174,12 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa Point[] directionPoints = convertWindFixListIntoPointsArray(windTrackInfoDTO.windFixes, WindType.DIRECTION); - trueWindSpeedLiveAverageComponent.updateValues( + trueWindSpeedLiveAverageComponent.setValues( "" + NumberFormat.getFormat("#0.0").format( speedPoints[speedPoints.length - 1].getY().doubleValue()), "" + NumberFormat.getFormat("#0.0").format(movingAverageSpeed.getAverage())); - trueWindDirectionLiveAverageComponent.updateValues( + trueWindDirectionLiveAverageComponent.setValues( "" + NumberFormat.getFormat("#0.0").format( directionPoints[directionPoints.length - 1].getY().doubleValue()), "" diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java index b2ed2e1facb..b8765bf03f1 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java @@ -31,8 +31,6 @@ import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.server.RacingEventService; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; -import com.sap.sse.common.Util; -import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; /** @@ -273,17 +271,29 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib } @Override - public List> getAdvantagesOnStartline(String leaderboardName) { + public List getAdvantagesOnStartline(String leaderboardName) { return generateRandomAdvantagesOnStartline(); } - private List> generateRandomAdvantagesOnStartline(){ - List> randomAdvantagesOnStartline = new ArrayList>(); - for(int i = 0; i <= 100; i = i+20){ - randomAdvantagesOnStartline.add(new Pair(new Double(i), new Double((i+1)/2+(0 + (int)(Math.random()*5))))); + private List generateRandomAdvantagesOnStartline(){ + List randomAdvantagesOnStartline = new ArrayList(); + for(int i = 0; i <= 100; i = i+10){ + randomAdvantagesOnStartline.add(getRandomStartLineAdvantageDTOWithX(i)); } return randomAdvantagesOnStartline; } + + private StartLineAdvantageDTO getRandomStartLineAdvantageDTOWithX(int x) { + StartLineAdvantageDTO result = new StartLineAdvantageDTO(); + result.distanceToRCBoatInMeters = x; + result.startLineAdvantage = (x+1)/2+(0 + (int)(Math.random()*5)); + if(x >= 50) { + result.confidence = 1; + }else{ + result.confidence = 0.3; + } + return result; + } @Override public void notifyLiveTrackedRaceListenerAboutLiveTrackedRaceChange(TrackedRace trackedRace) { diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java index aa1a6d33a6b..d0e552bdf35 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java @@ -7,7 +7,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import com.sap.sailing.dashboards.gwt.server.LiveTrackedRaceListener; -import com.sap.sailing.dashboards.gwt.server.RibDashboardServiceImpl; import com.sap.sailing.domain.base.Course; import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Waypoint; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/StartlineAdvantageCalculationBasis.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/StartlineAdvantageCalculationBasis.java new file mode 100644 index 00000000000..c9178e8bd74 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/StartlineAdvantageCalculationBasis.java @@ -0,0 +1,18 @@ +package com.sap.sailing.dashboards.gwt.shared; + +import com.google.gwt.user.client.rpc.IsSerializable; +import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; + +/** + * @author Alexander Ries (D062114) + * + */ +public enum StartlineAdvantageCalculationBasis implements IsSerializable { + MEASURED, + + /** + * When the {@link StartLineAdvantageDTO} is calculated with the Polar API and there are not values returned + * there are used manually entered polar values to provide still a {@link StartLineAdvantageDTO}. + */ + DEFAULT_VALUES +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java index 96965b47b59..0a69ac7f43c 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java @@ -5,10 +5,11 @@ import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAdvantageTyp public class StartLineAdvantageDTO implements IsSerializable { - public StartlineAdvantageType startLineAdvatageType; public double startLineAdvantage; public double startlineAdvantageAverage; public double distanceToRCBoatInMeters; + public StartlineAdvantageType startLineAdvatageType; + public double confidence; public StartLineAdvantageDTO(){} } From 7cd46452e1d73eb16fdf4d2fcf0e459527ced97e Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 12:29:14 +0200 Subject: [PATCH 012/167] added no proxy launch config for OSX --- .../SailingServer (No Proxy OSX).launch | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch new file mode 100644 index 00000000000..f26a44952df --- /dev/null +++ b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 94e11fef3f7d13810526a381c0c871afbf921d94 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 12:30:31 +0200 Subject: [PATCH 013/167] dashboard project compliance set to se8 to use be able to use java 8 features on server code --- java/com.sap.sailing.dashboards.gwt/.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/.classpath b/java/com.sap.sailing.dashboards.gwt/.classpath index ef84586018d..3c32839e434 100644 --- a/java/com.sap.sailing.dashboards.gwt/.classpath +++ b/java/com.sap.sailing.dashboards.gwt/.classpath @@ -7,6 +7,6 @@ - + diff --git a/java/com.sap.sailing.dashboards.gwt/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sailing.dashboards.gwt/.settings/org.eclipse.jdt.core.prefs index d17b6724d17..a698e59674f 100644 --- a/java/com.sap.sailing.dashboards.gwt/.settings/org.eclipse.jdt.core.prefs +++ b/java/com.sap.sailing.dashboards.gwt/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,12 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 From 12bba02afd76c3cd40166b8a7efaf85b1d63e79c Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 15:51:58 +0200 Subject: [PATCH 014/167] made averagedto and advantageswithmaxandminDTO serializable --- .../dashboards/gwt/shared/dto/AverageDTO.java | 15 +++++++++++++++ ...StartlineAdvantagesWithMaxAndAverageDTO.java | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/AverageDTO.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartlineAdvantagesWithMaxAndAverageDTO.java diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/AverageDTO.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/AverageDTO.java new file mode 100644 index 00000000000..540ccffa8a1 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/AverageDTO.java @@ -0,0 +1,15 @@ +package com.sap.sailing.dashboards.gwt.shared.dto; + +import com.google.gwt.user.client.rpc.IsSerializable; + +/** + * @author Alexander Ries (D062114) + * + */ +public class AverageDTO implements IsSerializable { + + public double average; + public double collectingTimeFrameInMilliseconds; + + public AverageDTO(){} +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartlineAdvantagesWithMaxAndAverageDTO.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartlineAdvantagesWithMaxAndAverageDTO.java new file mode 100644 index 00000000000..58c74a7973d --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartlineAdvantagesWithMaxAndAverageDTO.java @@ -0,0 +1,17 @@ +package com.sap.sailing.dashboards.gwt.shared.dto; + +import java.util.List; + +import com.google.gwt.user.client.rpc.IsSerializable; + +/** + * @author Alexander Ries (D062114) + * + */ +public class StartlineAdvantagesWithMaxAndAverageDTO extends AverageDTO implements IsSerializable { + + public double maximum; + public List advantages; + + public StartlineAdvantagesWithMaxAndAverageDTO(){} +} From b873908f953f9ee02c0744e0f154dc92ebae5891 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 16:10:53 +0200 Subject: [PATCH 015/167] added NumberTickingAnimation --- .../visualeffects/NumberTickingAnimation.java | 60 +++++++++++++++++++ .../visualeffects/NumberValueSetter.java | 13 ++++ 2 files changed, 73 insertions(+) create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java create mode 100644 java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberValueSetter.java diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java new file mode 100644 index 00000000000..3dde76f8c81 --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java @@ -0,0 +1,60 @@ +package com.sap.sailing.dashboards.gwt.client.visualeffects; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.i18n.client.NumberFormat; +import com.google.gwt.user.client.Timer; + +/** + * Animates number values changes in the UI as ticking animation. Requires a method to change the value of the corresponding UI element. + * + * @author Alexander Ries (D062114) + * + */ +public abstract class NumberTickingAnimation implements NumberValueSetter { + + private double previousNumber = 0; + private Timer timer; + int counter = 0; + List animationNumberStrings; + private final int ANIMATION_TIME_IN_MILLISECONDS = 1000; + + public void execute(double number) { + animationNumberStrings = getValuesBetweenDoubleOldAndNewNumber(number); + int animationTimePerNumber = ANIMATION_TIME_IN_MILLISECONDS/animationNumberStrings.size(); + timer = new Timer() { + @Override + public void run() { + if(animationNumberStrings.size() > counter) { + String value = animationNumberStrings.get(counter); + setValueInUI(value); + counter++; + }else { + timer.cancel(); + counter = 0; + } + } + }; + timer.scheduleRepeating(animationTimePerNumber); + } + + private List getValuesBetweenDoubleOldAndNewNumber(double number) { + List result = new ArrayList(); + double counter = previousNumber; + if (previousNumber < number) { + while (counter <= number) { + counter = counter + 0.1; + result.add(NumberFormat.getFormat("#0.0").format(counter)); + } + } else { + while (counter >= number) { + counter = counter - 0.1; + result.add(NumberFormat.getFormat("#0.0").format(counter)); + } + } + previousNumber = number; + return result; + } + +} diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberValueSetter.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberValueSetter.java new file mode 100644 index 00000000000..3283fefd72d --- /dev/null +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberValueSetter.java @@ -0,0 +1,13 @@ +package com.sap.sailing.dashboards.gwt.client.visualeffects; + +/** + * @author Alexander Ries (D062114) + * + */ +public interface NumberValueSetter { + + /** + * Implement the new value setting of a UI Element; + */ + public void setValueInUI(String value); +} \ No newline at end of file From 041f9d65cdf8e1b11b34c0fb4fbe74eee9d465d1 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 16:12:00 +0200 Subject: [PATCH 016/167] changed RibdashboardService --- .../gwt/client/RibDashboardService.java | 4 +-- .../gwt/client/RibDashboardServiceAsync.java | 4 +-- .../gwt/server/RibDashboardServiceImpl.java | 32 ++++++------------- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java index e2cdae773d3..75bb5fbb7ea 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardService.java @@ -4,7 +4,7 @@ import java.util.List; import com.google.gwt.user.client.rpc.RemoteService; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; -import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; +import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.dto.CompetitorDTO; @@ -16,5 +16,5 @@ public interface RibDashboardService extends RemoteService { List getCompetitorsInLeaderboard(String leaderboardName); - List getAdvantagesOnStartline(String leaderboardName); + StartlineAdvantagesWithMaxAndAverageDTO getAdvantagesOnStartline(String leaderboardName); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java index 6c67d39b9d1..378bf3e9bc7 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/RibDashboardServiceAsync.java @@ -4,7 +4,7 @@ import java.util.List; import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; -import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; +import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; @@ -16,5 +16,5 @@ public interface RibDashboardServiceAsync { void getCompetitorsInLeaderboard(String leaderboardName, AsyncCallback> callback); - void getAdvantagesOnStartline(String leaderboardName, AsyncCallback> callback); + void getAdvantagesOnStartline(String leaderboardName, AsyncCallback callback); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java index b8765bf03f1..0b8ffd9f14f 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/RibDashboardServiceImpl.java @@ -14,10 +14,12 @@ import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.sap.sailing.dashboards.gwt.client.RibDashboardService; import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAdvantageType; import com.sap.sailing.dashboards.gwt.server.startanalysis.StartAnalysisCreationController; +import com.sap.sailing.dashboards.gwt.server.startlineadvantages.StartlineAdvantagesCalculator; import com.sap.sailing.dashboards.gwt.shared.MovingAverage; import com.sap.sailing.dashboards.gwt.shared.ResponseMessage; import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO; import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; +import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Fleet; @@ -47,6 +49,8 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib private static final long serialVersionUID = 1L; private StartAnalysisCreationController startAnalysisCreationController; + + private StartlineAdvantagesCalculator startlineAdvantagesCalculator; /** * Variable contains last {@link TrackedRace} that is or was live @@ -78,6 +82,7 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib racingEventServiceTracker = createAndOpenRacingEventServiceTracker(context); baseDomainFactory = getRacingEventService().getBaseDomainFactory(); startAnalysisCreationController = new StartAnalysisCreationController(getRacingEventService()); + startlineAdvantagesCalculator = new StartlineAdvantagesCalculator(); averageStartLineAdvantageByWind = new MovingAverage(400); averageStartLineAdvantageByGeometry = new MovingAverage(400); @@ -195,13 +200,13 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib double startlineAdvantage = runningRace.getStartLine(timePoint).getAdvantage().getMeters(); startLineAdvantageDTO.startLineAdvantage = startlineAdvantage; averageStartLineAdvantageByWind.add(startlineAdvantage); - startLineAdvantageDTO.startlineAdvantageAverage = averageStartLineAdvantageByWind.getAverage(); + startLineAdvantageDTO.average = averageStartLineAdvantageByWind.getAverage(); } else if (startlineAdvantageType == StartlineAdvantageType.GEOMETRIC) { startLineAdvantageDTO.startLineAdvatageType = StartlineAdvantageType.GEOMETRIC; double startlineAdvantage = runningRace.getStartLine(timePoint).getAdvantage().getMeters(); startLineAdvantageDTO.startLineAdvantage = startlineAdvantage; averageStartLineAdvantageByGeometry.add(startlineAdvantage); - startLineAdvantageDTO.startlineAdvantageAverage = averageStartLineAdvantageByGeometry.getAverage(); + startLineAdvantageDTO.average = averageStartLineAdvantageByGeometry.getAverage(); } lRInfo.startLineAdvantageDTO = startLineAdvantageDTO; } @@ -271,29 +276,10 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib } @Override - public List getAdvantagesOnStartline(String leaderboardName) { - return generateRandomAdvantagesOnStartline(); + public StartlineAdvantagesWithMaxAndAverageDTO getAdvantagesOnStartline(String leaderboardName) { + return startlineAdvantagesCalculator.getStartLineAdvantagesAccrossLineAtTimePoint(MillisecondsTimePoint.now()); } - private List generateRandomAdvantagesOnStartline(){ - List randomAdvantagesOnStartline = new ArrayList(); - for(int i = 0; i <= 100; i = i+10){ - randomAdvantagesOnStartline.add(getRandomStartLineAdvantageDTOWithX(i)); - } - return randomAdvantagesOnStartline; - } - - private StartLineAdvantageDTO getRandomStartLineAdvantageDTOWithX(int x) { - StartLineAdvantageDTO result = new StartLineAdvantageDTO(); - result.distanceToRCBoatInMeters = x; - result.startLineAdvantage = (x+1)/2+(0 + (int)(Math.random()*5)); - if(x >= 50) { - result.confidence = 1; - }else{ - result.confidence = 0.3; - } - return result; - } @Override public void notifyLiveTrackedRaceListenerAboutLiveTrackedRaceChange(TrackedRace trackedRace) { From 2c3b5e75ddbbc44ab7b51015b187130be701918a Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 16:13:22 +0200 Subject: [PATCH 017/167] startlineadvantages use now NumberTickingAnimation for number value changes --- .../actions/GetStartlineAdvantagesAction.java | 8 +-- .../LiveAverageComponent.java | 5 +- .../StartLineAdvantageComponent.java | 8 +-- .../StartlineAdvantagesByWindComponent.java | 42 +++++++++++--- .../StartlineAdvantagesOnLineChart.java | 9 --- .../client/windchart/WindBotComponent.java | 16 ++--- .../StartlineAdvantagesCalculator.java | 58 ++++++++++++++++--- .../gwt/shared/dto/StartLineAdvantageDTO.java | 12 +++- 8 files changed, 109 insertions(+), 49 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java index dc237513d0b..1cf2be86c81 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetStartlineAdvantagesAction.java @@ -5,14 +5,12 @@ package com.sap.sailing.dashboards.gwt.client.actions; * */ -import java.util.List; - import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; -import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; +import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sse.gwt.client.async.AsyncAction; -public class GetStartlineAdvantagesAction implements AsyncAction> { +public class GetStartlineAdvantagesAction implements AsyncAction { private final RibDashboardServiceAsync ribDashboardService; private final String leaderboardName; @@ -23,6 +21,6 @@ public class GetStartlineAdvantagesAction implements AsyncAction> callback) { + public void execute(AsyncCallback callback) { ribDashboardService.getAdvantagesOnStartline(leaderboardName, callback); }} \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java index 0f84b6882c9..381054971c0 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java @@ -100,8 +100,11 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"
"+stringConstants.dashboardAverageWindMinutes(15)); } - public void setValues(String liveValue, String averageValue) { + public void setLiveValue(String liveValue) { this.liveNumber.setInnerText(liveValue); + } + + public void setAverageValue(String averageValue) { this.averageNumber.setInnerText(averageValue); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java index 928814cb605..35a3a0e7f66 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java @@ -100,7 +100,7 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements String liveValue = NumberFormat.getFormat("#0.0").format( liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage); String averageValue = NumberFormat.getFormat("#0.0").format( - liveRaceInfoDTO.startLineAdvantageDTO.startlineAdvantageAverage); + liveRaceInfoDTO.startLineAdvantageDTO.average); startLineAdvantageComponent.liveNumber.setInnerText(liveValue); startLineAdvantageComponent.averageNumber.setInnerText(averageValue); lastLiveValue = liveValue; @@ -108,7 +108,7 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByGeometry.lastLiveValue = NumberFormat .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage); startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByGeometry.lastAverageValue = NumberFormat - .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startlineAdvantageAverage); + .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.average); } @Override @@ -133,7 +133,7 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements String liveValue = NumberFormat.getFormat("#0.0").format( liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage); String averageValue = NumberFormat.getFormat("#0.0").format( - liveRaceInfoDTO.startLineAdvantageDTO.startlineAdvantageAverage); + liveRaceInfoDTO.startLineAdvantageDTO.average); startLineAdvantageComponent.liveNumber.setInnerText(liveValue); startLineAdvantageComponent.averageNumber.setInnerText(averageValue); lastLiveValue = liveValue; @@ -141,7 +141,7 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByWind.lastLiveValue = NumberFormat .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage); startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByWind.lastAverageValue = NumberFormat - .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startlineAdvantageAverage); + .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.average); } @Override diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java index 4c6071d688e..fcf56159765 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java @@ -2,8 +2,8 @@ package com.sap.sailing.dashboards.gwt.client.startlineadvantage; import java.util.Date; import java.util.Iterator; -import java.util.List; +import com.gargoylesoftware.htmlunit.javascript.host.Console; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.resources.client.CssResource; @@ -15,8 +15,10 @@ import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesAction; -import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; +import com.sap.sailing.dashboards.gwt.client.visualeffects.NumberTickingAnimation; +import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.common.Util; import com.sap.sse.gwt.client.async.AsyncActionsExecutor; import com.sap.sse.gwt.client.player.TimeListener; import com.sap.sse.gwt.client.player.Timer; @@ -49,7 +51,8 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has private RibDashboardServiceAsync ribDashboardService; private AsyncActionsExecutor asyncActionsExecutor; - private String leaderboardName; + private NumberTickingAnimation maximumTickingAnimation; + private NumberTickingAnimation averageTickingAnimation; public StartlineAdvantagesByWindComponent(RibDashboardServiceAsync ribDashboardService) { startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart(); @@ -57,25 +60,45 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has advantageMaximumLiveAverage.header.getStyle().setFontSize(14, Unit.PT); advantageMaximumLiveAverage.liveLabel.setInnerHTML("advantage max."); advantageMaximumLiveAverage.averageLabel.setInnerHTML("advantage max. average "+StringMessages.INSTANCE.dashboardAverageWindMinutes(15)); + initTickingAnimations(); initWidget(uiBinder.createAndBindUi(this)); this.ribDashboardService = ribDashboardService; this.asyncActionsExecutor = new AsyncActionsExecutor(); initSampleTimer(); } + private void initTickingAnimations() { + maximumTickingAnimation = new NumberTickingAnimation() { + + @Override + public void setValueInUI(String value) { + advantageMaximumLiveAverage.setLiveValue(value); + } + }; + + averageTickingAnimation = new NumberTickingAnimation() { + + @Override + public void setValueInUI(String value) { + advantageMaximumLiveAverage.setAverageValue(value); + } + }; + } + private void loadData() { GetStartlineAdvantagesAction getRibDashboardRaceInfoAction = new GetStartlineAdvantagesAction( ribDashboardService, ""); - asyncActionsExecutor.execute(getRibDashboardRaceInfoAction, new AsyncCallback>() { + asyncActionsExecutor.execute(getRibDashboardRaceInfoAction, new AsyncCallback() { @Override public void onFailure(Throwable caught) { } @Override - public void onSuccess(List result) { - startlineAdvantagesOnLineChart.setStartlineAdvantages(result); - advantageMaximumLiveAverage.setValues("44.2", "23.1"); + public void onSuccess(StartlineAdvantagesWithMaxAndAverageDTO result) { + startlineAdvantagesOnLineChart.setStartlineAdvantages(result.advantages); + maximumTickingAnimation.execute(result.maximum); + averageTickingAnimation.execute(result.average); } }); @@ -83,11 +106,11 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has private void initSampleTimer(){ Timer timer = new Timer(PlayModes.Live); - timer.setRefreshInterval(3000); + timer.setRefreshInterval(5000); timer.addTimeListener(this); timer.play(); } - + @Override public void add(Widget w) { throw new UnsupportedOperationException("The method add(Widget w) is not supported."); @@ -112,4 +135,5 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has public void timeChanged(Date newTime, Date oldTime) { loadData(); } + } \ No newline at end of file diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java index 139940ee60d..d01ce9ab0f1 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java @@ -1,6 +1,5 @@ package com.sap.sailing.dashboards.gwt.client.startlineadvantage; -import java.util.Date; import java.util.Iterator; import java.util.List; @@ -28,21 +27,13 @@ import com.google.gwt.dom.client.DivElement; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; -import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; -import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesAction; import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sse.common.Util.Pair; -import com.sap.sse.gwt.client.async.AsyncActionsExecutor; -import com.sap.sse.gwt.client.player.TimeListener; -import com.sap.sse.gwt.client.player.Timer; -import com.sap.sse.gwt.client.player.Timer.PlayModes; /** * @author Alexander Ries (D062114) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java index ffd1c4dac49..8ac0d2978e5 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/windchart/WindBotComponent.java @@ -174,16 +174,12 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa Point[] directionPoints = convertWindFixListIntoPointsArray(windTrackInfoDTO.windFixes, WindType.DIRECTION); - trueWindSpeedLiveAverageComponent.setValues( - "" - + NumberFormat.getFormat("#0.0").format( - speedPoints[speedPoints.length - 1].getY().doubleValue()), "" - + NumberFormat.getFormat("#0.0").format(movingAverageSpeed.getAverage())); - trueWindDirectionLiveAverageComponent.setValues( - "" - + NumberFormat.getFormat("#0.0").format( - directionPoints[directionPoints.length - 1].getY().doubleValue()), "" - + NumberFormat.getFormat("#0.0").format(movingAverageDirection.getAverage())); + trueWindSpeedLiveAverageComponent.setLiveValue(""+NumberFormat.getFormat("#0.0").format(speedPoints[speedPoints.length - 1].getY().doubleValue())); + trueWindSpeedLiveAverageComponent.setAverageValue(""+NumberFormat.getFormat("#0.0").format(movingAverageSpeed.getAverage())); + + trueWindDirectionLiveAverageComponent.setLiveValue(""+NumberFormat.getFormat("#0.0").format(directionPoints[directionPoints.length - 1].getY().doubleValue())); + trueWindDirectionLiveAverageComponent.setAverageValue(""+NumberFormat.getFormat("#0.0").format(movingAverageDirection.getAverage())); + trueWindSpeedVerticalWindChart.addPointsToSeriesWithAverage(speedPoints, movingAverageSpeed.getAverage()); trueWindDirectionVerticalWindChart.addPointsToSeriesWithAverage(directionPoints, diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java index d0e552bdf35..81ce9d4c5f4 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/startlineadvantages/StartlineAdvantagesCalculator.java @@ -1,12 +1,15 @@ package com.sap.sailing.dashboards.gwt.server.startlineadvantages; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Set; -import java.util.logging.Level; import java.util.logging.Logger; import com.sap.sailing.dashboards.gwt.server.LiveTrackedRaceListener; +import com.sap.sailing.dashboards.gwt.shared.MovingAverage; +import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; +import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sailing.domain.base.Course; import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Waypoint; @@ -27,14 +30,22 @@ public class StartlineAdvantagesCalculator implements LiveTrackedRaceListener{ private TrackedRace currentLiveTrackedRace; private Pair startlineMarkPositions; private Position firstMarkPosition; + private MovingAverage advantageMaximumAverage; private static final Logger logger = Logger.getLogger(StartlineAdvantagesCalculator.class.getName()); public StartlineAdvantagesCalculator(){ + advantageMaximumAverage = new MovingAverage(500); } - public Map getStartLineAdvantagesAccrossLine(){ - Map result = new HashMap(); + public StartlineAdvantagesWithMaxAndAverageDTO getStartLineAdvantagesAccrossLineAtTimePoint(TimePoint timepoint){ + StartlineAdvantagesWithMaxAndAverageDTO result = new StartlineAdvantagesWithMaxAndAverageDTO(); + List advantages = generateRandomAdvantagesOnStartline(); + result.advantages = advantages; + double maximum = getMaximumAdvantageOfStartlineAdvantageDTOs(advantages); + result.maximum = maximum; + advantageMaximumAverage.add(maximum); + result.average = advantageMaximumAverage.getAverage(); // Get Course Buoys // Get Wind // Get Maneuver Angle and Boat Speed at Angle @@ -45,10 +56,39 @@ public class StartlineAdvantagesCalculator implements LiveTrackedRaceListener{ // Calculate duration from two new distances for normal upwind starts // Put all durations in one set // Get the smallest of the durations and subtract number from every other number - retrieveFirstLegWayPoints(); - logger.log(Level.INFO, "Startline Startboat : "+startlineMarkPositions.getA()); - logger.log(Level.INFO, "Startline PinEnd: "+startlineMarkPositions.getB()); - logger.log(Level.INFO, "Firstmark: "+firstMarkPosition); +// retrieveFirstLegWayPoints(); +// logger.log(Level.INFO, "Startline Startboat : "+startlineMarkPositions.getA()); +// logger.log(Level.INFO, "Startline PinEnd: "+startlineMarkPositions.getB()); +// logger.log(Level.INFO, "Firstmark: "+firstMarkPosition); + return result; + } + + private double getMaximumAdvantageOfStartlineAdvantageDTOs(List advantages) { + double result = 0; + if(advantages != null && advantages.size() > 0) { + Collections.sort(advantages, StartLineAdvantageDTO.startlineAdvantageComparatorDesc); + result = advantages.get(0).startLineAdvantage; + } + return result; + } + + private List generateRandomAdvantagesOnStartline(){ + List randomAdvantagesOnStartline = new ArrayList(); + for(int i = 0; i <= 100; i = i+10){ + randomAdvantagesOnStartline.add(getRandomStartLineAdvantageDTOWithX(i)); + } + return randomAdvantagesOnStartline; + } + + private StartLineAdvantageDTO getRandomStartLineAdvantageDTOWithX(int x) { + StartLineAdvantageDTO result = new StartLineAdvantageDTO(); + result.distanceToRCBoatInMeters = x; + result.startLineAdvantage = (x+1)/2+(0 + (int)(Math.random()*5)); + if(x >= 50) { + result.confidence = 1; + }else{ + result.confidence = 0.3; + } return result; } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java index 0a69ac7f43c..3052bcb8fc7 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/StartLineAdvantageDTO.java @@ -1,15 +1,23 @@ package com.sap.sailing.dashboards.gwt.shared.dto; +import java.util.Comparator; + import com.google.gwt.user.client.rpc.IsSerializable; import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAdvantageType; -public class StartLineAdvantageDTO implements IsSerializable { +public class StartLineAdvantageDTO extends AverageDTO implements IsSerializable { public double startLineAdvantage; - public double startlineAdvantageAverage; public double distanceToRCBoatInMeters; public StartlineAdvantageType startLineAdvatageType; public double confidence; public StartLineAdvantageDTO(){} + + public static Comparator startlineAdvantageComparatorDesc = new Comparator() { + public int compare(StartLineAdvantageDTO a, StartLineAdvantageDTO b) { + return (int) (b.startLineAdvantage - a.startLineAdvantage); + } + + }; } From 27d8649856866db6b1bc4e7cc218d5dda318cae3 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 16:14:19 +0200 Subject: [PATCH 018/167] removed unused imports --- .../startlineadvantage/StartlineAdvantagesByWindComponent.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java index fcf56159765..2f583e7f0bb 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java @@ -3,7 +3,6 @@ package com.sap.sailing.dashboards.gwt.client.startlineadvantage; import java.util.Date; import java.util.Iterator; -import com.gargoylesoftware.htmlunit.javascript.host.Console; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.resources.client.CssResource; @@ -18,7 +17,6 @@ import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesActio import com.sap.sailing.dashboards.gwt.client.visualeffects.NumberTickingAnimation; import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sse.common.Util; import com.sap.sse.gwt.client.async.AsyncActionsExecutor; import com.sap.sse.gwt.client.player.TimeListener; import com.sap.sse.gwt.client.player.Timer; From 752906bed4ac1fd1bc03d6c724c32bb41cf27939 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 16:44:30 +0200 Subject: [PATCH 019/167] added NumberTickingAnimation to LiveAverageComponent --- .../LiveAverageComponent.java | 27 +++++++++++++++++-- .../StartlineAdvantagesByWindComponent.java | 26 ++---------------- .../visualeffects/NumberTickingAnimation.java | 5 ++-- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java index 381054971c0..4dee67a2a67 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/LiveAverageComponent.java @@ -12,6 +12,7 @@ import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.dashboards.gwt.client.visualeffects.NumberTickingAnimation; import com.sap.sailing.dashboards.gwt.client.windchart.VerticalWindChartClickListener; import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent; import com.sap.sailing.gwt.ui.client.StringMessages; @@ -73,6 +74,9 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti LiveAverageComponentStyle style; private StringMessages stringConstants; + private NumberTickingAnimation liveTickingAnimation; + private NumberTickingAnimation averageTickingAnimation; + public LiveAverageComponent() { initWidget(uiBinder.createAndBindUi(this)); } @@ -86,6 +90,7 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti * */ public LiveAverageComponent(String header, String unit) { stringConstants = StringMessages.INSTANCE; + initTickingAnimations(); initWidget(uiBinder.createAndBindUi(this)); liveAveragePanel.getElement().getStyle().setProperty("backgroundColor", "white"); this.header.setInnerText(header); @@ -99,13 +104,31 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti this.liveLabel.setInnerHTML(stringConstants.dashboardLiveWind()); this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"
"+stringConstants.dashboardAverageWindMinutes(15)); } + + private void initTickingAnimations() { + liveTickingAnimation = new NumberTickingAnimation() { + + @Override + public void setValueInUI(String value) { + liveNumber.setInnerText(value); + } + }; + + averageTickingAnimation = new NumberTickingAnimation() { + + @Override + public void setValueInUI(String value) { + averageNumber.setInnerText(value); + } + }; + } public void setLiveValue(String liveValue) { - this.liveNumber.setInnerText(liveValue); + liveTickingAnimation.execute(liveValue); } public void setAverageValue(String averageValue) { - this.averageNumber.setInnerText(averageValue); + averageTickingAnimation.execute(averageValue); } @Override diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java index 2f583e7f0bb..304db2c6d03 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesByWindComponent.java @@ -14,7 +14,6 @@ import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync; import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesAction; -import com.sap.sailing.dashboards.gwt.client.visualeffects.NumberTickingAnimation; import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sse.gwt.client.async.AsyncActionsExecutor; @@ -49,8 +48,6 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has private RibDashboardServiceAsync ribDashboardService; private AsyncActionsExecutor asyncActionsExecutor; - private NumberTickingAnimation maximumTickingAnimation; - private NumberTickingAnimation averageTickingAnimation; public StartlineAdvantagesByWindComponent(RibDashboardServiceAsync ribDashboardService) { startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart(); @@ -58,31 +55,12 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has advantageMaximumLiveAverage.header.getStyle().setFontSize(14, Unit.PT); advantageMaximumLiveAverage.liveLabel.setInnerHTML("advantage max."); advantageMaximumLiveAverage.averageLabel.setInnerHTML("advantage max. average "+StringMessages.INSTANCE.dashboardAverageWindMinutes(15)); - initTickingAnimations(); initWidget(uiBinder.createAndBindUi(this)); this.ribDashboardService = ribDashboardService; this.asyncActionsExecutor = new AsyncActionsExecutor(); initSampleTimer(); } - private void initTickingAnimations() { - maximumTickingAnimation = new NumberTickingAnimation() { - - @Override - public void setValueInUI(String value) { - advantageMaximumLiveAverage.setLiveValue(value); - } - }; - - averageTickingAnimation = new NumberTickingAnimation() { - - @Override - public void setValueInUI(String value) { - advantageMaximumLiveAverage.setAverageValue(value); - } - }; - } - private void loadData() { GetStartlineAdvantagesAction getRibDashboardRaceInfoAction = new GetStartlineAdvantagesAction( ribDashboardService, ""); @@ -95,8 +73,8 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has @Override public void onSuccess(StartlineAdvantagesWithMaxAndAverageDTO result) { startlineAdvantagesOnLineChart.setStartlineAdvantages(result.advantages); - maximumTickingAnimation.execute(result.maximum); - averageTickingAnimation.execute(result.average); + advantageMaximumLiveAverage.setLiveValue(""+result.maximum); + advantageMaximumLiveAverage.setAverageValue(""+result.average); } }); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java index 3dde76f8c81..0be6748a4d7 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java @@ -20,8 +20,9 @@ public abstract class NumberTickingAnimation implements NumberValueSetter { List animationNumberStrings; private final int ANIMATION_TIME_IN_MILLISECONDS = 1000; - public void execute(double number) { - animationNumberStrings = getValuesBetweenDoubleOldAndNewNumber(number); + public void execute(String numberString) { + double numberAsDouble = Double.parseDouble(numberString); + animationNumberStrings = getValuesBetweenDoubleOldAndNewNumber(numberAsDouble); int animationTimePerNumber = ANIMATION_TIME_IN_MILLISECONDS/animationNumberStrings.size(); timer = new Timer() { @Override From 8f7c648deea0a48ae3b88b763ed719a230b08fdb Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 17:25:16 +0200 Subject: [PATCH 020/167] StartlineAdvantageComponent uses now NumberTickingAnimation --- .../StartLineAdvantageComponent.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java index 35a3a0e7f66..3096a16c612 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartLineAdvantageComponent.java @@ -105,10 +105,10 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements startLineAdvantageComponent.averageNumber.setInnerText(averageValue); lastLiveValue = liveValue; lastAverageValue = averageValue; - startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByGeometry.lastLiveValue = NumberFormat - .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage); - startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByGeometry.lastAverageValue = NumberFormat - .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.average); + setLiveValue(NumberFormat + .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage)); + setAverageValue(NumberFormat + .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.average)); } @Override @@ -138,10 +138,10 @@ public class StartLineAdvantageComponent extends LiveAverageComponent implements startLineAdvantageComponent.averageNumber.setInnerText(averageValue); lastLiveValue = liveValue; lastAverageValue = averageValue; - startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByWind.lastLiveValue = NumberFormat - .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage); - startLineAdvantageComponent.startLineAdvantageComponentStateShowsAdvantageByWind.lastAverageValue = NumberFormat - .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.average); + setLiveValue(NumberFormat + .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage)); + setAverageValue(NumberFormat + .getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.average)); } @Override From 93c7880238012d4959d8e4a415c2dfd3db4ad514 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 17:52:19 +0200 Subject: [PATCH 021/167] added startlineadvantagechart style settings --- .../StartlineAdvantagesOnLineChart.java | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java index d01ce9ab0f1..a332ce830c0 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/startlineadvantage/StartlineAdvantagesOnLineChart.java @@ -94,6 +94,12 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg .setLegend(new Legend().setEnabled(false)) .setToolTip(new ToolTip().setEnabled(false)) .setCredits(new Credits().setEnabled(false)) + .setBackgroundColor("#FFFFFF") + .setBorderColor("#FFFFFF") + .setPlotShadow(false) + .setPlotBorderColor("#FFFFFF") + .setOption("/exporting/enabled", false) + .setShadow(false) .setStyle(new Style().setPosition("absolute").setTop("0px").setBottom("0px").setLeft("0px").setRight("0px")) .setAnimation(true); chart.setSize("100%", "100%"); @@ -124,23 +130,25 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg .setLineWidth(1) .setLineColor("grey") .setTickColor("grey") + .setGridLineColor("white") .setTickWidth(1) + .setGridLineWidth(0) .setReversed(true); } - private void setYAxisOfChart(Chart chart){ - chart.getYAxis() - .setAxisTitle(new AxisTitle().setText(StringMessages.INSTANCE.dashboardAdvantageInSeconds()).setStyle(new Style().setFontFamily("Open Sans") - .setFontSize("14") - .setColor("black").setFontWeight("bold"))) - .setLabels(new YAxisLabels() - .setFormatter(new AxisLabelsFormatter() { - public String format(AxisLabelsData axisLabelsData) { + private void setYAxisOfChart(Chart chart) { + chart.getYAxis() + .setAxisTitle( + new AxisTitle().setText(StringMessages.INSTANCE.dashboardAdvantageInSeconds()).setStyle( + new Style().setFontFamily("Open Sans").setFontSize("14").setColor("black") + .setFontWeight("bold"))) + .setLabels(new YAxisLabels().setFormatter(new AxisLabelsFormatter() { + public String format(AxisLabelsData axisLabelsData) { return String.valueOf(axisLabelsData.getValueAsLong()); - } - } - ).setStyle(new Style().setFontFamily("Open Sans").setFontSize("12") - .setColor("grey"))).setLineColor("grey").setTickWidth(1).setTickColor("grey").setLineWidth(1).setGridLineWidth(0); + } + }).setStyle(new Style().setFontFamily("Open Sans").setFontSize("12").setColor("grey"))) + .setLineColor("grey").setGridLineWidth(0).setMinorGridLineWidth(0).setGridLineColor("white") + .setTickWidth(1).setTickColor("grey").setLineWidth(1).setGridLineWidth(0); } private Series createSeries(Chart chart){ From db2cb367300343a84b79ab38e557ef97381b43da Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 20:11:23 +0200 Subject: [PATCH 022/167] fixed small counting bug with NumberTickingAnimation --- .../visualeffects/NumberTickingAnimation.java | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java index 0be6748a4d7..78b36ac5d3d 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java @@ -1,10 +1,14 @@ package com.sap.sailing.dashboards.gwt.client.visualeffects; import java.util.ArrayList; +import java.util.Date; import java.util.List; import com.google.gwt.i18n.client.NumberFormat; -import com.google.gwt.user.client.Timer; +import com.sap.sse.gwt.client.player.TimeListener; +import com.sap.sse.gwt.client.player.Timer; +import com.sap.sse.gwt.client.player.Timer.PlayModes; + /** * Animates number values changes in the UI as ticking animation. Requires a method to change the value of the corresponding UI element. @@ -12,33 +16,30 @@ import com.google.gwt.user.client.Timer; * @author Alexander Ries (D062114) * */ -public abstract class NumberTickingAnimation implements NumberValueSetter { +public abstract class NumberTickingAnimation implements NumberValueSetter, TimeListener { private double previousNumber = 0; - private Timer timer; int counter = 0; + Timer timer; List animationNumberStrings; private final int ANIMATION_TIME_IN_MILLISECONDS = 1000; - public void execute(String numberString) { - double numberAsDouble = Double.parseDouble(numberString); - animationNumberStrings = getValuesBetweenDoubleOldAndNewNumber(numberAsDouble); - int animationTimePerNumber = ANIMATION_TIME_IN_MILLISECONDS/animationNumberStrings.size(); - timer = new Timer() { - @Override - public void run() { - if(animationNumberStrings.size() > counter) { - String value = animationNumberStrings.get(counter); - setValueInUI(value); - counter++; - }else { - timer.cancel(); - counter = 0; - } - } - }; - timer.scheduleRepeating(animationTimePerNumber); - } + public NumberTickingAnimation(){ + animationNumberStrings = new ArrayList(); + timer = new Timer(PlayModes.Live); + } + + public void execute(String numberString) { + //if (!timer.getPlayState().equals(Timer.PlayStates.Playing)) { + double numberAsDouble = Double.parseDouble(numberString); + animationNumberStrings.clear(); + animationNumberStrings = getValuesBetweenDoubleOldAndNewNumber(numberAsDouble); + int animationTimePerNumber = ANIMATION_TIME_IN_MILLISECONDS / animationNumberStrings.size(); + timer.setRefreshInterval(animationTimePerNumber); + timer.addTimeListener(this); + timer.play(); + //} + } private List getValuesBetweenDoubleOldAndNewNumber(double number) { List result = new ArrayList(); @@ -58,4 +59,16 @@ public abstract class NumberTickingAnimation implements NumberValueSetter { return result; } + @Override + public void timeChanged(Date newTime, Date oldTime) { + if (animationNumberStrings.size() > counter) { + String value = animationNumberStrings.get(counter); + setValueInUI(value); + counter++; + } else { + timer.pause(); + timer.removeTimeListener(this); + counter = 0; + } + } } From 44baa3ce83fa9f482c0da141abb2e4f0d1c06fc2 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Wed, 15 Jul 2015 20:12:04 +0200 Subject: [PATCH 023/167] removed some comments --- .../gwt/client/visualeffects/NumberTickingAnimation.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java index 78b36ac5d3d..da24dc5a819 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/visualeffects/NumberTickingAnimation.java @@ -30,7 +30,6 @@ public abstract class NumberTickingAnimation implements NumberValueSetter, TimeL } public void execute(String numberString) { - //if (!timer.getPlayState().equals(Timer.PlayStates.Playing)) { double numberAsDouble = Double.parseDouble(numberString); animationNumberStrings.clear(); animationNumberStrings = getValuesBetweenDoubleOldAndNewNumber(numberAsDouble); @@ -38,7 +37,6 @@ public abstract class NumberTickingAnimation implements NumberValueSetter, TimeL timer.setRefreshInterval(animationTimePerNumber); timer.addTimeListener(this); timer.play(); - //} } private List getValuesBetweenDoubleOldAndNewNumber(double number) { From e058d398b23a8301b023f7c01042c222694ad036 Mon Sep 17 00:00:00 2001 From: Alexander Ries Date: Thu, 16 Jul 2015 00:42:33 +0200 Subject: [PATCH 024/167] Revert "Merge remote-tracking branch 'origin/master' into ribdashboard-newstartlineadvantage" This reverts commit 2124fa8582ba33e2e9e916344cf1c3f1d3e85c38, reversing changes made to 752906bed4ac1fd1bc03d6c724c32bb41cf27939. --- configuration/sailing | 40 +- configuration/sailing.sh | 17 - home.md | 2 +- java/CodeFormatter_IntelliJ.jar | Bin 2439 -> 1688 bytes .../RibDashboard.html | 1 + .../dashboards/gwt/RibDashboard.gwt.xml | 3 +- .../domain/common/AbstractPosition.java | 22 +- .../domain/common/BoatClassMasterdata.java | 16 +- .../sailing/domain/common/FleetColors.java | 5 +- .../sap/sailing/domain/common/Position.java | 12 +- .../impl/DomainObjectFactoryImpl.java | 16 +- .../domain/persistence/impl/FieldNames.java | 1 - .../impl/MongoObjectFactoryImpl.java | 49 +- .../impl/MongoRaceLogStoreVisitor.java | 24 +- .../impl/RaceLogRaceTracker.java | 43 +- .../racelog/state/test/RaceStateTest.java | 17 +- .../abstractlog/race/CompetitorResults.java | 4 - ...gEvent.java => FixedMarkPassingEvent.java} | 2 +- .../race/RaceLogEndOfTrackingEvent.java | 6 - .../abstractlog/race/RaceLogEventFactory.java | 12 +- .../abstractlog/race/RaceLogEventVisitor.java | 8 +- .../race/RaceLogStartOfTrackingEvent.java | 5 - ....java => SuppressedMarkPassingsEvent.java} | 2 +- .../analyzing/impl/MarkPassingDataFinder.java | 12 +- .../impl/AbstractRaceLogChangedVisitor.java | 20 +- .../race/impl/BaseRaceLogEventVisitor.java | 20 +- ...pl.java => FixedMarkPassingEventImpl.java} | 6 +- .../race/impl/RaceLogChangedVisitor.java | 6 - .../impl/RaceLogEndOfTrackingEventImpl.java | 26 - .../race/impl/RaceLogEventFactoryImpl.java | 24 +- .../impl/RaceLogStartOfTrackingEventImpl.java | 25 - ...a => SuppressedMarkPassingsEventImpl.java} | 6 +- .../race/impl/WeakRaceLogChangedVisitor.java | 13 +- .../impl/BaseRacingProcedure.java | 14 +- .../sap/sailing/domain/base/EventBase.java | 8 - .../src/com/sap/sailing/domain/base/Leg.java | 17 +- .../domain/base/impl/CourseDataImpl.java | 2 + .../domain/base/impl/EventBaseImpl.java | 11 - ...stFarthestAheadWithSkippedMarkPassing.java | 204 -- ...ationVersusOneDesignRankingMetricTest.java | 2 +- .../domain/test/mock/MockedTrackedRace.java | 9 +- .../tractracadapter/impl/Simulator.java | 41 +- .../impl/TracTracRaceTrackerImpl.java | 9 +- .../domain/base/impl/AbstractRaceColumn.java | 2 - .../sailing/domain/base/impl/CourseImpl.java | 14 +- .../sap/sailing/domain/base/impl/LegImpl.java | 10 - .../impl/RaceColumnRaceLogReplicator.java | 20 +- .../domain/leaderboard/Leaderboard.java | 8 +- .../impl/AbstractSimpleLeaderboardImpl.java | 35 +- .../leaderboard/impl/ScoreCorrectionImpl.java | 11 +- .../sailing/domain/tracking/GPSFixTrack.java | 2 - .../tracking/TrackedLegOfCompetitor.java | 4 +- .../domain/tracking/TrackedRegatta.java | 5 +- .../impl/AbstractRaceRankComparator.java | 47 +- .../impl/DynamicTrackedRaceLogListener.java | 14 +- .../domain/tracking/impl/GPSFixTrackImpl.java | 2 + .../impl/MarkPassingByTimeComparator.java | 31 +- ...ssingsByTimeAndCompetitorIdComparator.java | 36 - .../domain/tracking/impl/TrackedLegImpl.java | 2 +- .../impl/TrackedLegOfCompetitorImpl.java | 30 +- .../domain/tracking/impl/TrackedRaceImpl.java | 4 +- .../tracking/impl/TrackedRegattaImpl.java | 95 +- .../raceanalysis.product | 4 +- .../gwt/ui/test/MockedTrackedRace.java | 10 +- .../.tmp/gwt-work/.gitignore | 1 - java/com.sap.sailing.gwt.ui/AdminConsole.html | 4 + java/com.sap.sailing.gwt.ui/AutoPlay.html | 6 + .../BrowserUnsupported.html | 15 + .../CommonControls.css | 0 java/com.sap.sailing.gwt.ui/DataMining.html | 8 +- java/com.sap.sailing.gwt.ui/Home.html | 79 +- java/com.sap.sailing.gwt.ui/HomeDesktop.html | 22 - java/com.sap.sailing.gwt.ui/HomeMobile.html | 22 - java/com.sap.sailing.gwt.ui/Leaderboard.html | 12 +- .../LeaderboardEditing.html | 1 + java/com.sap.sailing.gwt.ui/PolarSheets.html | 7 +- java/com.sap.sailing.gwt.ui/RaceBoard.html | 5 + .../RegattaOverview.html | 1 + .../SailingGWT sdm.launch | 153 +- java/com.sap.sailing.gwt.ui/SailingGWT.launch | 151 +- java/com.sap.sailing.gwt.ui/Simulator.html | 10 +- java/com.sap.sailing.gwt.ui/Spectator.html | 1 + .../gwt/ui/leaderboard => }/ViewerToolbar.css | 39 + java/com.sap.sailing.gwt.ui/WEB-INF/web.xml | 5 +- java/com.sap.sailing.gwt.ui/build.properties | 7 +- .../js/adapters/standalone-framework.js | 0 .../js/adapters/standalone-framework.src.js | 0 .../highcharts/js/highcharts-3d.js | 0 .../highcharts/js/highcharts-3d.src.js | 0 .../highcharts/js/highcharts-all.js | 0 .../highcharts/js/highcharts-more.js | 0 .../highcharts/js/highcharts-more.src.js | 0 .../highcharts/js/highcharts.js | 0 .../highcharts/js/highcharts.src.js | 0 .../highcharts/js/modules/canvas-tools.js | 0 .../highcharts/js/modules/canvas-tools.src.js | 0 .../legacy => }/highcharts/js/modules/data.js | 0 .../highcharts/js/modules/data.src.js | 0 .../highcharts/js/modules/drilldown.js | 0 .../highcharts/js/modules/drilldown.src.js | 0 .../highcharts/js/modules/exporting.js | 0 .../highcharts/js/modules/exporting.src.js | 0 .../highcharts/js/modules/funnel.js | 0 .../highcharts/js/modules/funnel.src.js | 0 .../highcharts/js/modules/heatmap.js | 0 .../highcharts/js/modules/heatmap.src.js | 0 .../js/modules/no-data-to-display.js | 0 .../js/modules/no-data-to-display.src.js | 0 .../highcharts/js/modules/solid-gauge.js | 0 .../highcharts/js/modules/solid-gauge.src.js | 0 .../highcharts/js/themes/dark-blue.js | 0 .../highcharts/js/themes/dark-green.js | 0 .../highcharts/js/themes/dark-unica.js | 0 .../legacy => }/highcharts/js/themes/gray.js | 0 .../highcharts/js/themes/grid-light.js | 0 .../legacy => }/highcharts/js/themes/grid.js | 0 .../highcharts/js/themes/sand-signika.js | 0 .../legacy => }/highcharts/js/themes/skies.js | 0 .../images/mobile/arrow-down-grey.png | Bin 865 -> 0 bytes .../images/mobile/arrow-grey-right.png | Bin 308 -> 0 bytes .../images/mobile/calender-icon-blue.svg | 1 - .../images/mobile/fastest_sailor.svg | 16 - .../images/mobile/icon_averageSpeed.svg | 1 - .../images/mobile/icon_racesCount.svg | 1 - .../images/mobile/icon_regattasFought.svg | 1 - .../images/mobile/icon_trackedCount.svg | 1 - .../images/mobile/logo-small@2x.png | Bin 6388 -> 0 bytes .../images/mobile/navigation-icon.svg | 1 - .../images/mobile/quickfinder-arrow.svg | 1 - .../images/mobile/raw_gps_fixes.svg | 21 - .../images/mobile/search-icon.svg | 1 - .../images/mobile/strongest_wind.svg | 11 - .../images/mobile/sum_miles.svg | 8 - .../js/video-js/demo.captions.vtt | 41 + .../js/video-js/demo.html | 32 + .../js/video-js/video-js-sapsailing.css | 2 + .../js/video-js/video-js.css | 36 +- .../js/video-js/video-js.less | 1 - .../js/video-js/video-js.min.css | 4 +- .../js/video-js/video-js.swf | Bin 17485 -> 17202 bytes .../js/video-js/video.dev.js | 87 +- .../js/video-js/video.js | 370 +- .../js/video-js/video.novtt.dev.js | 87 +- .../js/video-js/video.novtt.js | 368 +- java/com.sap.sailing.gwt.ui/js/vjs.vimeo.js | 11 +- java/com.sap.sailing.gwt.ui/js/vjs.youtube.js | 1098 +----- java/com.sap.sailing.gwt.ui/pom.xml | 2 +- .../sailing/gwt/common/SourceCommon.gwt.xml | 11 - .../common/client/BoatClassImageResolver.java | 11 - .../client/BoatClassImageResources.java | 33 - .../sailing/gwt/common/client/LinkUtil.java | 18 - .../client/controls/tabbar/TabPanel.java | 10 +- .../com/sap/sailing/gwt/home/Desktop.gwt.xml | 49 - .../com/sap/sailing/gwt/home/Home.gwt.xml | 10 - .../com/sap/sailing/gwt/home/Mobile.gwt.xml | 39 - .../HomeEntryPoint.java} | 20 +- .../app/AbstractApplicationClientFactory.java | 15 +- .../app/AbstractPlaceNavigator.java | 11 +- .../client/app/ApplicationActivityMapper.java | 171 + .../app/ApplicationClientFactory.java} | 6 +- .../app/ApplicationHistoryMapper.java | 11 +- .../app/ApplicationTopLevelView.java | 2 +- .../app/HomePlacesNavigator.java} | 7 +- .../app/PlaceNavigation.java | 38 +- .../app/PlaceNavigator.java | 2 +- .../SmartphoneApplicationClientFactory.java | 79 + .../client/app/SmartphoneApplicationView.java | 60 + .../app/SmartphoneApplicationView.ui.xml | 15 + ...letAndDesktopApplicationClientFactory.java | 10 +- .../app/TabletAndDesktopApplicationView.java | 10 +- .../TabletAndDesktopApplicationView.ui.xml} | 7 +- .../place/event/AbstractEventActivity.java | 12 +- .../place/event/AbstractEventPlace.java | 8 +- .../place/event/EventActivityProxy.java | 20 +- .../place/event/EventClientFactory.java | 2 +- .../home/client/place/event/EventContext.java | 3 +- .../client/place/event/EventDefaultPlace.java | 3 +- .../client/place/event/EventPrefixes.java | 3 - .../home/client/place/event/EventView.java | 4 +- .../EventMultiregattaActivity.java | 4 +- .../TabletAndDesktopEventView.java | 6 +- .../tabs/MultiregattaOverviewPlace.java | 3 +- .../event/overview/EventOverviewStage.java | 6 +- .../client/place/event/partials/Regatta.java | 11 +- .../place/event/partials/RegattaPhase.java | 2 +- .../event/partials/countdown/Countdown.java | 2 +- .../eventregatta/EventRegattaList.java | 18 +- .../event/partials/header/EventHeader.java | 71 +- .../event/partials/header/EventHeader.ui.xml | 7 +- .../partials/raceListLive/RacesListLive.java | 2 +- .../partials/racelist/AbstractRaceList.java | 4 +- .../partials/regattaHeader/RegattaHeader.css | 79 + .../partials/regattaHeader/RegattaHeader.java | 26 + .../regattaHeader/RegattaHeader.ui.xml | 30 + .../regattaHeader/RegattaHeaderBody.ui.xml | 59 + .../regattaHeader/RegattaHeaderResources.java | 23 + .../regattaraces/EventRegattaRaces.java | 9 +- .../regattaraces/EventRegattaRaces.ui.xml | 2 +- .../event/partials/updatesBox/UpdatesBox.gss | 2 + .../event/partials/updatesBox/UpdatesBox.java | 5 +- .../partials/updatesBox/UpdatesBoxItem.java | 5 +- .../place/event/partials/video/Video.java | 8 +- .../place/event/partials/video/Video.ui.xml | 5 +- .../event/regatta/EventRegattaActivity.java | 6 +- .../place/event/regatta/EventRegattaView.java | 2 +- .../regatta/TabletAndDesktopEventView.java | 4 +- .../regatta/tabs/reload/RefreshManager.java | 10 +- .../home/client/place/events/EventsPlace.java | 10 +- .../events/TabletAndDesktopEventsView.java | 8 +- .../events/recent/EventsOverviewRecent.java | 6 +- .../recent/EventsOverviewRecentYear.java | 6 +- .../events/recent/RecentEventTeaser.java | 5 +- .../upcoming/EventsOverviewUpcoming.java | 6 +- .../upcoming/EventsOverviewUpcomingEvent.java | 6 +- .../fakeseries/AbstractSeriesActivity.java | 10 +- .../place/fakeseries/SeriesActivity.java | 10 +- .../place/fakeseries/SeriesActivityProxy.java | 30 +- .../place/fakeseries/SeriesDefaultPlace.java | 3 +- .../client/place/fakeseries/SeriesView.java | 2 +- .../TabletAndDesktopSeriesView.java | 4 +- .../partials/header/SeriesHeader.java | 2 +- .../fakeseries/tabs/SeriesEventsTabView.java | 2 +- .../fakeseries/tabs/SeriesOverviewPlace.java | 3 +- .../TabletAndDesktopSearchResultView.java | 4 +- .../TabletAndDesktopSolutionsView.java | 4 +- .../place/start/SmartphoneStartView.java | 4 +- .../place/start/SmartphoneStartView.ui.xml | 5 +- .../home/client/place/start/StartPlace.java | 9 +- .../start/TabletAndDesktopStartView.java | 4 +- .../start/TabletAndDesktopStartView.ui.xml | 4 +- .../TabletAndDesktopWhatsNewView.java | 6 +- .../gwt/home/client/shared/ButtonType.java | 5 - .../gwt/home/client/shared/ButtonUtil.java | 20 - .../home/client/shared/DropdownHandler.java | 88 - .../gwt/home/client/shared/LabelTypeUtil.java | 14 - .../dispatch/AutomaticBatchingDispatch.java | 2 +- .../shared/dispatch/DispatchAsync.java | 2 +- .../shared/dispatch/DispatchCall.java | 2 +- .../shared/dispatch/DispatchCallStack.java | 2 +- .../shared/dispatch/DispatchSystem.java | 5 + .../shared/dispatch/DispatchSystemImpl.java | 17 + .../shared/dispatch/SimpleDispatch.java | 32 +- .../home/client/shared/event/EventTeaser.java | 10 +- .../shared}/footer/Footer.gss | 0 .../shared}/footer/Footer.java | 26 +- .../shared}/footer/Footer.ui.xml | 8 +- .../shared}/footer/FooterResources.java | 4 +- .../shared}/header/Header.gss | 0 .../shared}/header/Header.java | 12 +- .../shared}/header/Header.ui.xml | 2 +- .../shared}/header/HeaderResources.java | 4 +- .../client/shared/lowerThird/LowerThird.gss | 43 - .../client/shared/lowerThird/LowerThird.java | 89 - .../shared/lowerThird/LowerThird.ui.xml | 24 - .../lowerThird/LowerThirdResources.java | 22 - .../client/shared/mainevents/MainEvents.java | 8 +- .../client/shared/mainmedia/MainMedia.css | 4 +- .../client/shared/mainmedia/MainMedia.java | 2 +- .../shared/mainmedia/MainMediaVideo.java | 18 +- .../shared/mainmedia/MainMediaVideo.ui.xml | 4 +- .../shared/mainsponsors/MainSponsors.java | 8 +- .../home/client/shared/media/MediaPage.java | 6 +- .../home/client/shared/media/MediaPage.ui.xml | 34 +- .../shared/searchresult/SearchResult.java | 8 +- .../shared/searchresult/SearchResultItem.java | 8 +- .../shared}/socialfooter/SocialFooter.gss | 0 .../shared}/socialfooter/SocialFooter.java | 2 +- .../shared}/socialfooter/SocialFooter.ui.xml | 2 +- .../socialfooter/SocialFooterResources.java | 2 +- .../client/shared/solutions/Solutions.java | 8 +- .../shared/stage/LiveEventStageTeaser.java | 4 +- .../shared/stage/LiveStageTeaserBand.java | 4 +- .../shared/stage/NoActionStageTeaserBand.java | 4 +- .../shared/stage/PopularEventStageTeaser.java | 4 +- .../stage/PopularEventStageTeaserBand.java | 4 +- .../gwt/home/client/shared/stage/Stage.java | 6 +- .../client/shared/stage/StageTeaserBand.java | 10 +- .../stage/UpcomingEventStageTeaser.java | 4 +- .../stage/UpcomingEventStageTeaserBand.java | 4 +- .../client/shared/videoPlayer/PlayButton.gss | 22 - .../client/shared/videoPlayer/PlayButton.java | 15 - .../videoPlayer/PlayButtonResources.java | 16 - .../client/shared/videoPlayer/VideoPlayer.gss | 4 - .../shared/videoPlayer/VideoPlayer.java | 80 - .../videoPlayer/VideoPlayerResources.java | 16 - .../videoPlayer/VideoWithLowerThird.java | 38 - .../desktop/app/AbstractPlaceNavigator.java | 55 - .../desktop/app/DesktopActivityMapper.java | 76 - .../TabletAndDesktopApplicationView.ui.xml | 19 - .../partials/socialfooter/SocialFooter.java | 20 - .../gwt/home/mobile/MobileEntryPoint.java | 29 - .../home/mobile/app/MobileActivityMapper.java | 59 - .../app/MobileApplicationClientFactory.java | 94 - .../mobile/app/MobilePlacesNavigator.java | 87 - .../mobile/partials/countdown/Countdown.gss | 137 - .../mobile/partials/countdown/Countdown.java | 128 - .../partials/countdown/Countdown.ui.xml | 30 - .../countdown/CountdownResources.java | 33 - .../partials/countdown/CountdownTicker.java | 60 - .../partials/countdown/CountdownTicker.ui.xml | 14 - .../partials/eventheader/EventHeader.gss | 141 - .../partials/eventheader/EventHeader.java | 53 - .../partials/eventheader/EventHeader.ui.xml | 48 - .../eventheader/EventHeaderResources.java | 40 - .../home/mobile/partials/footer/Footer.gss | 26 - .../home/mobile/partials/footer/Footer.java | 149 - .../home/mobile/partials/footer/Footer.ui.xml | 94 - .../partials/footer/FooterResources.java | 21 - .../home/mobile/partials/header/Header.gss | 133 - .../home/mobile/partials/header/Header.java | 86 - .../home/mobile/partials/header/Header.ui.xml | 41 - .../partials/header/HeaderNavigationItem.java | 37 - .../header/HeaderNavigationItem.ui.xml | 17 - .../partials/header/HeaderResources.java | 32 - .../impressions/ImpressionResources.java | 16 - .../partials/impressions/Impressions.gss | 3 - .../partials/impressions/Impressions.java | 82 - .../partials/impressions/Impressions.ui.xml | 17 - .../home/mobile/partials/message/Message.gss | 24 - .../home/mobile/partials/message/Message.java | 34 - .../mobile/partials/message/Message.ui.xml | 16 - .../partials/message/MessageResources.java | 20 - .../minileaderboard/MinileaderboardBox.java | 102 - .../minileaderboard/MinileaderboardBox.ui.xml | 16 - .../MinileaderboardBoxItem.java | 44 - .../MinileaderboardBoxItem.ui.xml | 67 - .../MinileaderboardBoxItemLegend.java | 17 - .../MinileaderboardBoxItemLegend.ui.xml | 59 - .../partials/quickfinder/Quickfinder.java | 99 - .../partials/quickfinder/Quickfinder.ui.xml | 40 - .../partials/recents/EventsOverviewRecent.gss | 201 -- .../recents/EventsOverviewRecent.java | 44 - .../recents/EventsOverviewRecent.ui.xml | 10 - .../EventsOverviewRecentResources.java | 53 - .../recents/EventsOverviewRecentYear.java | 91 - .../recents/EventsOverviewRecentYear.ui.xml | 61 - .../EventsOverviewRecentYearEvent.java | 65 - .../EventsOverviewRecentYearEvent.ui.xml | 30 - .../partials/regattaStatus/RegattaStatus.gss | 124 - .../partials/regattaStatus/RegattaStatus.java | 69 - .../regattaStatus/RegattaStatus.ui.xml | 23 - .../regattaStatus/RegattaStatusRace.java | 75 - .../regattaStatus/RegattaStatusRace.ui.xml | 37 - .../regattaStatus/RegattaStatusRegatta.java | 64 - .../regattaStatus/RegattaStatusRegatta.ui.xml | 12 - .../regattaStatus/RegattaStatusResources.java | 32 - .../partials/section/IsMobileSection.java | 7 - .../mobile/partials/section/MobileSection.gss | 27 - .../partials/section/MobileSection.java | 66 - .../partials/section/MobileSection.ui.xml | 21 - .../section/MobileSectionResources.java | 21 - .../partials/sectionHeader/SectionHeader.gss | 90 - .../sectionHeader/SectionHeader.ui.xml | 25 - .../sectionHeader/SectionHeaderContent.java | 100 - .../sectionHeader/SectionHeaderContent.ui.xml | 26 - .../sectionHeader/SectionHeaderResources.java | 28 - .../partials/seriesheader/SeriesHeader.gss | 141 - .../partials/seriesheader/SeriesHeader.java | 48 - .../partials/seriesheader/SeriesHeader.ui.xml | 37 - .../seriesheader/SeriesHeaderResources.java | 40 - .../simpleinfoblock/SimpleInfoBlock.java | 47 - .../simpleinfoblock/SimpleInfoBlock.ui.xml | 27 - .../partials/socialfooter/SocialFooter.gss | 50 - .../partials/socialfooter/SocialFooter.ui.xml | 40 - .../socialfooter/SocialFooterResources.java | 25 - .../partials/statisticsBox/StatisticsBox.gss | 58 - .../partials/statisticsBox/StatisticsBox.java | 104 - .../statisticsBox/StatisticsBox.ui.xml | 13 - .../statisticsBox/StatisticsBoxItem.java | 29 - .../statisticsBox/StatisticsBoxItem.ui.xml | 12 - .../statisticsBox/StatisticsBoxResources.java | 21 - .../partials/toggleButton/ToggleButton.gss | 13 - .../partials/toggleButton/ToggleButton.java | 57 - .../partials/toggleButton/ToggleButton.ui.xml | 10 - .../toggleButton/ToggleButtonResources.java | 17 - .../upcoming/EventsOverviewUpcoming.gss | 124 - .../upcoming/EventsOverviewUpcoming.java | 82 - .../upcoming/EventsOverviewUpcoming.ui.xml | 31 - .../upcoming/EventsOverviewUpcomingEvent.java | 51 - .../EventsOverviewUpcomingEvent.ui.xml | 34 - .../EventsOverviewUpcomingResources.java | 44 - .../updatesBox/NewsItemLinkProvider.java | 13 - .../mobile/partials/updatesBox/UpdatesBox.gss | 115 - .../partials/updatesBox/UpdatesBox.java | 92 - .../partials/updatesBox/UpdatesBox.ui.xml | 18 - .../partials/updatesBox/UpdatesBoxItem.java | 74 - .../partials/updatesBox/UpdatesBoxItem.ui.xml | 19 - .../updatesBox/UpdatesBoxResources.java | 27 - .../gwt/home/mobile/places/MainView.java | 65 - .../mobile/places/QuickfinderPresenter.java | 42 - .../RegattaLeaderboardNavigationProvider.java | 9 - .../SeriesLeaderboardNavigationProvider.java | 11 - .../mobile/places/event/EventActivity.java | 181 - .../places/event/EventActivityProxy.java | 27 - .../home/mobile/places/event/EventView.java | 40 - .../mobile/places/event/EventViewImpl.java | 139 - .../mobile/places/event/EventViewImpl.ui.xml | 30 - .../event/overview/EventOverviewStage.java | 61 - .../event/overview/EventOverviewStage.ui.xml | 17 - .../mobile/places/events/EventsActivity.java | 65 - .../places/events/EventsActivityProxy.java | 27 - .../home/mobile/places/events/EventsView.java | 22 - .../mobile/places/events/EventsViewImpl.java | 46 - .../places/events/EventsViewImpl.ui.xml | 17 - .../places/latestnews/LatestNewsActivity.java | 101 - .../latestnews/LatestNewsActivityProxy.java | 26 - .../places/latestnews/LatestNewsPlace.java | 51 - .../places/latestnews/LatestNewsView.java | 24 - .../places/latestnews/LatestNewsViewImpl.java | 45 - .../latestnews/LatestNewsViewImpl.ui.xml | 21 - .../MiniLeaderboardActivity.java | 102 - .../MiniLeaderboardActivityProxy.java | 26 - .../minileaderboard/MiniLeaderboardPlace.java | 32 - .../minileaderboard/MiniLeaderboardView.java | 29 - .../MiniLeaderboardViewImpl.java | 68 - .../MiniLeaderboardViewImpl.ui.xml | 31 - .../OverallLeaderboardNavigationProvider.java | 8 - .../mobile/places/series/SeriesActivity.java | 90 - .../places/series/SeriesActivityProxy.java | 27 - .../home/mobile/places/series/SeriesView.java | 24 - .../mobile/places/series/SeriesViewImpl.java | 78 - .../places/series/SeriesViewImpl.ui.xml | 27 - .../SeriesMiniOverallLeaderboardActivity.java | 84 - ...esMiniOverallLeaderboardActivityProxy.java | 26 - .../SeriesMiniOverallLeaderboardPlace.java | 32 - .../SeriesMiniOverallLeaderboardView.java | 23 - .../SeriesMiniOverallLeaderboardViewImpl.java | 50 - ...eriesMiniOverallLeaderboardViewImpl.ui.xml | 27 - .../mobile/places/start/StartActivity.java | 34 - .../places/start/StartActivityProxy.java | 27 - .../home/mobile/places/start/StartView.java | 13 - .../mobile/places/start/StartViewImpl.java | 34 - .../mobile/places/start/StartViewImpl.ui.xml | 18 - .../mobile/resources/SharedResources.java | 143 - .../gwt/home/mobile/resources/css/main.gss | 427 --- .../gwt/home/mobile/resources/css/media.gss | 450 --- .../gwt/home/shared/SwitchingEntryPoint.java | 178 - .../shared/app/ApplicationPlaceUpdater.java | 115 - .../gwt/home/shared/app/HasLocationTitle.java | 5 - .../gwt/home/shared/app/HasMobileVersion.java | 5 - .../home/shared/dispatch/DispatchSystem.java | 7 - .../shared/dispatch/DispatchSystemImpl.java | 42 - .../gwt/home/shared/utils/LogoUtil.java | 33 - .../regattaoverview/RegattaOverview.gwt.xml | 33 +- .../SourceRegattaOverview.gwt.xml | 11 - .../sailing/gwt/server/HomeServiceUtil.java | 104 +- .../sap/sailing/gwt/ui/AdminConsole.gwt.xml | 4 +- .../sap/sailing/gwt/ui/CommonConfigs.gwt.xml | 31 - .../com/sap/sailing/gwt/ui/Sources.gwt.xml | 10 + .../ui/adminconsole/EventCreateDialog.java | 2 - .../adminconsole/EventDetailsComposite.java | 6 +- .../gwt/ui/adminconsole/EventDialog.java | 22 +- .../gwt/ui/adminconsole/EventEditDialog.java | 2 - .../ui/adminconsole/EventListComposite.java | 5 +- .../LeaderboardGroupConfigPanel.java | 8 - .../ui/adminconsole/RegattaImportDialog.java | 107 + .../StructureImportManagementPanel.java | 2 +- .../gwt/ui/adminconsole/VideoDialog.java | 2 + .../gwt/ui/client/FlagImageResolver.java | 607 ++-- .../sailing/gwt/ui/client/SailingService.java | 4 +- .../gwt/ui/client/SailingServiceAsync.java | 4 +- .../sailing/gwt/ui/client/StringMessages.java | 24 - .../gwt/ui/client/StringMessages.properties | 29 +- .../ui/client/StringMessages_de.properties | 35 +- .../ui/client/StringMessages_ru.properties | 26 +- .../ui/client/StringMessages_zh.properties | 24 - .../gwt/ui/client/media/PauseEvent.java | 27 - .../gwt/ui/client/media/PlayEvent.java | 27 - .../gwt/ui/client/media/VideoJSPlayer.java | 82 +- .../gwt/ui/client/media/VideoJSPlayer.ui.xml | 23 +- .../shared/charts/EditMarkPassingsPanel.java | 18 +- .../BoatClassVectorGraphicsResolver.java | 14 +- .../client/DateAndTimeFormatterUtil.java | 11 +- .../AbstractLeaderboardViewer.java | 17 +- .../ui/leaderboard/LeaderboardEntryPoint.java | 608 ++-- .../gwt/ui/leaderboard/LeaderboardTable.css | 357 +- .../gwt/ui/leaderboard/SortedCellTable.java | 3 +- .../gwt/ui/leaderboard/ViewerToolbar.java | 25 - .../leaderboardedit/LeaderboardEditPage.java | 2 +- .../gwt/ui/server/SailingServiceImpl.java | 45 +- .../gwt/ui/server/SimulatorServiceImpl.java | 6 +- .../ui/server/dispatch/DispatchRPCImpl.java | 35 +- .../gwt/ui/shared/CompactRaceMapDataDTO.java | 4 +- .../sailing/gwt/ui/shared/EventBaseDTO.java | 9 - .../sailing/gwt/ui/shared/RaceMapDataDTO.java | 2 +- .../gwt/ui/shared/SimulatorResultsDTO.java | 13 +- .../gwt/ui/shared/dispatch/BatchAction.java | 13 - .../gwt/ui/shared/dispatch/ResultWithTTL.java | 3 +- .../dispatch/ServerDispatchException.java | 21 - .../dispatch/event/EventActionUtil.java | 110 - .../dispatch/event/EventStatisticsDTO.java | 97 - .../event/GetEventOverviewNewsAction.java | 26 +- .../event/GetEventOverviewStageAction.java | 3 +- .../event/GetEventStatisticsAction.java | 167 - .../dispatch/event/GetEventViewAction.java | 57 +- .../event/GetLiveRacesForEventAction.java | 27 +- .../event/GetLiveRacesForRegattaAction.java | 18 +- .../dispatch/event/GetMiniLeaderboardDTO.java | 57 - .../event/GetMiniLeaderbordAction.java | 34 - .../event/GetMiniOverallLeaderbordAction.java | 32 - .../dispatch/event/GetRaceListViewAction.java | 3 +- ...GetRegattasAndLiveRacesForEventAction.java | 89 - .../dispatch/event/LeaderboardContext.java | 80 - .../dispatch/event/LiveRaceCalculator.java | 2 +- .../shared/dispatch/event/LiveRacesDTO.java | 18 +- .../event/MiniLeaderboardItemDTO.java | 38 - .../shared/dispatch/event/NextRaceFinder.java | 2 +- .../ui/shared/dispatch/event/RaceContext.java | 137 +- .../dispatch/event/RacesActionUtil.java | 45 + .../event/RegattasAndLiveRacesDTO.java | 42 - .../dispatch/event/SimpleCompetitorDTO.java | 72 - .../news/AbstractRaceNewsEntryDTO.java | 4 +- .../dispatch/news/InfoNewsEntryDTO.java | 5 +- .../news/LeaderboardNewsEntryDTO.java | 6 +- .../ui/shared/dispatch/news/NewsEntryDTO.java | 13 +- .../news/RaceCompetitorNewsEntryDTO.java | 4 +- .../gwt/ui/shared/eventview/EventViewDTO.java | 27 +- .../shared/eventview/HasRegattaMetadata.java | 2 - .../shared/eventview/RegattaMetadataDTO.java | 9 - .../shared/eventview/RegattaReferenceDTO.java | 13 +- .../shared/fakeseries/EventSeriesViewDTO.java | 3 +- .../gwt/ui/shared/general/HasLogo.java | 8 - .../gwt/ui/shared/race/FleetMetadataDTO.java | 7 +- .../gwt/ui/shared/race/RaceMetadataDTO.java | 56 +- .../shared/racemap/RaceSimulationOverlay.java | 16 +- .../com/sap/sailing/gwt/AutoPlay.gwt.xml | 54 +- .../com/sap/sailing/gwt/Home.gwt.xml | 99 + .../com/sap/sailing/gwt/ui/DataMining.gwt.xml | 28 +- .../sap/sailing/gwt/ui/Leaderboard.gwt.xml | 59 +- .../sailing/gwt/ui/LeaderboardEditing.gwt.xml | 2 +- .../com/sap/sailing/gwt/ui/NoUI.gwt.xml | 2 +- .../sap/sailing/gwt/ui/PolarSheets.gwt.xml | 34 +- .../com/sap/sailing/gwt/ui/RaceBoard.gwt.xml | 30 +- .../com/sap/sailing/gwt/ui/Simulator.gwt.xml | 35 +- .../com/sap/sailing/gwt/ui/Spectator.gwt.xml | 30 +- .../com/sap/sailing/gwt/ui/VideoPopup.gwt.xml | 2 +- .../sap/sailing/gwt/ui/YoutubePopup.gwt.xml | 2 +- .../ui/client/images/boatclass/18FOOTER.png | Bin 8785 -> 0 bytes .../ui/client/images/boatclass/49ER_FX.png | Bin 18162 -> 2636 bytes .../ui/client/images/boatclass/CANOE_IC.png | Bin 9312 -> 0 bytes .../client/images/boatclass/CANOE_TAIFUN.png | Bin 2297 -> 0 bytes .../gwt/ui/client/images/boatclass/D_ONE.png | Bin 10455 -> 0 bytes .../gwt/ui/client/images/boatclass/FUN.png | Bin 20369 -> 0 bytes .../gwt/ui/client/images/boatclass/J22.png | Bin 6600 -> 0 bytes .../client/images/boatclass/KIELZUGVOGEL.png | Bin 2909 -> 0 bytes .../gwt/ui/client/images/boatclass/LASER2.png | Bin 2966 -> 0 bytes .../ui/client/images/boatclass/O_JOLLE.png | Bin 7733 -> 0 bytes .../ui/client/images/boatclass/RS_FEVA.png | Bin 22998 -> 0 bytes .../gwt/ui/client/images/boatclass/TRIAS.png | Bin 6039 -> 0 bytes .../mongodb/test/StoreCompetitorTest.java | 19 +- ...estStoringAndLoadingEventsAndRegattas.java | 6 +- .../sailing/selenium/pages/PageObject.java | 2 +- .../selenium/pages/gwt/CellTablePO.java | 2 +- ...RaceLogEndOfTrackingEventDeserializer.java | 29 - .../impl/RaceLogEventDeserializer.java | 27 +- ...ceLogStartOfTrackingEventDeserializer.java | 29 - .../impl/EventBaseJsonSerializer.java | 2 - ...eLogDependentStartTimeEventSerializer.java | 4 +- .../RaceLogEndOfTrackingEventSerializer.java | 22 - .../racelog/impl/RaceLogEventSerializer.java | 36 +- ...aceLogFixedMarkPassingEventSerializer.java | 6 +- ...RaceLogStartOfTrackingEventSerializer.java | 21 - ...SuppressedMarkPassingsEventSerializer.java | 6 +- .../racelog/RaceLogEventSerializerTest.java | 6 +- .../impl/RegattaJsonSerializer.java | 2 - .../impl/LeaderboardJsonGetServlet.java | 96 +- .../RegattaAndRaceDataJsonGetServlet.java | 12 +- .../jaxrs/api/CompetitorsResource.java | 7 +- .../gateway/jaxrs/api/RegattasResource.java | 4 +- .../server/test/MasterDataImportTest.java | 8 +- .../server/test/SearchServiceTest.java | 5 +- ...oxy, Jetty on 8889, auto-replicate).launch | 32 - ...ver (No Proxy, Remote Debug SAP VM).launch | 62 +- .../sailing/server/RacingEventService.java | 4 +- .../server/impl/RacingEventServiceImpl.java | 14 +- .../CreateEvent.java | 6 +- .../UpdateEvent.java | 6 +- .../server/simulation/SimulationService.java | 2 +- .../simulation/SimulationServiceImpl.java | 11 +- .../sailing/simulator/SimulationResults.java | 9 +- .../adminconsole/URLFieldWithFileUpload.java | 2 +- java/com.sap.sse.gwt/META-INF/MANIFEST.MF | 3 +- .../com/sap/sse/gwt/CommonControlCSS.gwt.xml | 6 - .../gwt/CommonControlCSS_Autoinject.gwt.xml | 8 - .../src/com/sap/sse/gwt/Highcharts.gwt.xml | 7 - .../sap/sse/gwt/Highcharts_Autoinject.gwt.xml | 7 - .../sse/gwt/resources/CommonControlsCSS.java | 17 - .../CommonControlsInjectingEntryPoint.java | 10 - .../com/sap/sse/gwt/resources/Highcharts.java | 21 - .../HighchartsInjectingEntryPoint.java | 12 - .../sse/gwt/resources/LegacyResources.java | 27 - .../js/adapters/standalone-framework.js | 18 - .../js/adapters/standalone-framework.src.js | 590 ---- .../highcharts/js/modules/canvas-tools.js | 133 - .../highcharts/js/modules/canvas-tools.src.js | 3113 ----------------- .../resources/highcharts/js/modules/data.js | 16 - .../highcharts/js/modules/data.src.js | 607 ---- .../highcharts/js/modules/drilldown.js | 14 - .../highcharts/js/modules/drilldown.src.js | 585 ---- .../highcharts/js/modules/exporting.js | 22 - .../highcharts/js/modules/exporting.src.js | 715 ---- .../resources/highcharts/js/modules/funnel.js | 13 - .../highcharts/js/modules/funnel.src.js | 310 -- .../highcharts/js/modules/heatmap.js | 21 - .../highcharts/js/modules/heatmap.src.js | 606 ---- .../js/modules/no-data-to-display.js | 12 - .../js/modules/no-data-to-display.src.js | 130 - .../highcharts/js/modules/solid-gauge.js | 13 - .../highcharts/js/modules/solid-gauge.src.js | 224 -- .../highcharts/js/themes/dark-blue.js | 254 -- .../highcharts/js/themes/dark-green.js | 255 -- .../highcharts/js/themes/dark-unica.js | 213 -- .../resources/highcharts/js/themes/gray.js | 257 -- .../highcharts/js/themes/grid-light.js | 74 - .../resources/highcharts/js/themes/grid.js | 103 - .../highcharts/js/themes/sand-signika.js | 101 - .../resources/highcharts/js/themes/skies.js | 89 - .../sse/replication/ReplicationService.java | 14 +- .../sap/sse/replication/impl/Activator.java | 17 +- .../impl/ReplicableWithObjectInputStream.java | 10 +- .../impl/ReplicationServiceImpl.java | 16 +- .../replication/impl/ReplicationServlet.java | 2 - .../.tmp/gwt-work/.gitignore | 1 - .../Security UI sdm.launch | 97 +- java/target/refreshInstance.sh | 5 +- .../ByNameCourseDesignDialog.java | 2 + wiki/amazon-ec2.md | 2 +- wiki/racelog-tracking.md | 3 - wiki/smartphone-tracking.md | 24 - 629 files changed, 3797 insertions(+), 24352 deletions(-) delete mode 100644 configuration/sailing.sh rename java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/{RaceLogFixedMarkPassingEvent.java => FixedMarkPassingEvent.java} (73%) delete mode 100755 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEndOfTrackingEvent.java delete mode 100755 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogStartOfTrackingEvent.java rename java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/{RaceLogSuppressedMarkPassingsEvent.java => SuppressedMarkPassingsEvent.java} (65%) rename java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/{RaceLogFixedMarkPassingEventImpl.java => FixedMarkPassingEventImpl.java} (79%) delete mode 100755 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEndOfTrackingEventImpl.java delete mode 100755 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogStartOfTrackingEventImpl.java rename java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/{RaceLogSuppressedMarkPassingsEventImpl.java => SuppressedMarkPassingsEventImpl.java} (74%) delete mode 100755 java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/ranking/TestFarthestAheadWithSkippedMarkPassing.java delete mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingsByTimeAndCompetitorIdComparator.java delete mode 100644 java/com.sap.sailing.gwt.ui/.tmp/gwt-work/.gitignore rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources/css => com.sap.sailing.gwt.ui}/CommonControls.css (100%) delete mode 100644 java/com.sap.sailing.gwt.ui/HomeDesktop.html delete mode 100644 java/com.sap.sailing.gwt.ui/HomeMobile.html rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/leaderboard => }/ViewerToolbar.css (70%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/adapters/standalone-framework.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/adapters/standalone-framework.src.js (100%) rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources => com.sap.sailing.gwt.ui}/highcharts/js/highcharts-3d.js (100%) rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources => com.sap.sailing.gwt.ui}/highcharts/js/highcharts-3d.src.js (100%) rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources => com.sap.sailing.gwt.ui}/highcharts/js/highcharts-all.js (100%) rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources => com.sap.sailing.gwt.ui}/highcharts/js/highcharts-more.js (100%) rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources => com.sap.sailing.gwt.ui}/highcharts/js/highcharts-more.src.js (100%) rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources => com.sap.sailing.gwt.ui}/highcharts/js/highcharts.js (100%) rename java/{com.sap.sse.gwt/src/com/sap/sse/gwt/resources => com.sap.sailing.gwt.ui}/highcharts/js/highcharts.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/canvas-tools.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/canvas-tools.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/data.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/data.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/drilldown.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/drilldown.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/exporting.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/exporting.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/funnel.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/funnel.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/heatmap.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/heatmap.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/no-data-to-display.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/no-data-to-display.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/solid-gauge.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/modules/solid-gauge.src.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/dark-blue.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/dark-green.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/dark-unica.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/gray.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/grid-light.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/grid.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/sand-signika.js (100%) rename java/com.sap.sailing.gwt.ui/{src/main/java/com/sap/sailing/gwt/ui/legacy => }/highcharts/js/themes/skies.js (100%) delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/arrow-down-grey.png delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/arrow-grey-right.png delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/calender-icon-blue.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/fastest_sailor.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/icon_averageSpeed.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/icon_racesCount.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/icon_regattasFought.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/icon_trackedCount.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/logo-small@2x.png delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/navigation-icon.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/quickfinder-arrow.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/raw_gps_fixes.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/search-icon.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/strongest_wind.svg delete mode 100644 java/com.sap.sailing.gwt.ui/images/mobile/sum_miles.svg create mode 100644 java/com.sap.sailing.gwt.ui/js/video-js/demo.captions.vtt create mode 100644 java/com.sap.sailing.gwt.ui/js/video-js/demo.html delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/SourceCommon.gwt.xml delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/Desktop.gwt.xml delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/Home.gwt.xml delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/Mobile.gwt.xml rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/DesktopEntryPoint.java => client/HomeEntryPoint.java} (58%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop => client}/app/AbstractApplicationClientFactory.java (78%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{mobile => client}/app/AbstractPlaceNavigator.java (84%) create mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/ApplicationActivityMapper.java rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/app/DesktopClientFactory.java => client/app/ApplicationClientFactory.java} (83%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{shared => client}/app/ApplicationHistoryMapper.java (86%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop => client}/app/ApplicationTopLevelView.java (77%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/app/DesktopPlacesNavigator.java => client/app/HomePlacesNavigator.java} (95%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{shared => client}/app/PlaceNavigation.java (66%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{shared => client}/app/PlaceNavigator.java (77%) create mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/SmartphoneApplicationClientFactory.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/SmartphoneApplicationView.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/app/SmartphoneApplicationView.ui.xml rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop => client}/app/TabletAndDesktopApplicationClientFactory.java (88%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop => client}/app/TabletAndDesktopApplicationView.java (84%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{mobile/places/MainView.ui.xml => client/app/TabletAndDesktopApplicationView.ui.xml} (68%) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.css create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeader.ui.xml create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderBody.ui.xml create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/partials/regattaHeader/RegattaHeaderResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/ButtonType.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/ButtonUtil.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/DropdownHandler.java rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{ => client}/shared/dispatch/AutomaticBatchingDispatch.java (98%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{ => client}/shared/dispatch/DispatchAsync.java (83%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{ => client}/shared/dispatch/DispatchCall.java (91%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{ => client}/shared/dispatch/DispatchCallStack.java (98%) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/dispatch/DispatchSystem.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/dispatch/DispatchSystemImpl.java rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{ => client}/shared/dispatch/SimpleDispatch.java (65%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/footer/Footer.gss (100%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/footer/Footer.java (82%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/footer/Footer.ui.xml (89%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/footer/FooterResources.java (82%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/header/Header.gss (100%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/header/Header.java (93%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/header/Header.ui.xml (95%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/header/HeaderResources.java (86%) delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/lowerThird/LowerThird.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/lowerThird/LowerThird.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/lowerThird/LowerThird.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/lowerThird/LowerThirdResources.java rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/socialfooter/SocialFooter.gss (100%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{mobile/partials => client/shared}/socialfooter/SocialFooter.java (89%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/socialfooter/SocialFooter.ui.xml (95%) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/{desktop/partials => client/shared}/socialfooter/SocialFooterResources.java (93%) delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/videoPlayer/PlayButton.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/videoPlayer/PlayButton.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/videoPlayer/PlayButtonResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/videoPlayer/VideoPlayer.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/videoPlayer/VideoPlayer.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/videoPlayer/VideoPlayerResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/shared/videoPlayer/VideoWithLowerThird.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/app/AbstractPlaceNavigator.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/app/DesktopActivityMapper.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/app/TabletAndDesktopApplicationView.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/partials/socialfooter/SocialFooter.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/MobileEntryPoint.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/app/MobileActivityMapper.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/app/MobileApplicationClientFactory.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/app/MobilePlacesNavigator.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/countdown/Countdown.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/countdown/Countdown.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/countdown/Countdown.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/countdown/CountdownResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/countdown/CountdownTicker.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/countdown/CountdownTicker.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventheader/EventHeader.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventheader/EventHeader.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventheader/EventHeader.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/eventheader/EventHeaderResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/Footer.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/footer/FooterResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/header/Header.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/header/Header.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/header/Header.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/header/HeaderNavigationItem.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/header/HeaderNavigationItem.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/header/HeaderResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/impressions/ImpressionResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/impressions/Impressions.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/impressions/Impressions.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/impressions/Impressions.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/message/Message.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/message/Message.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/message/Message.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/message/MessageResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/minileaderboard/MinileaderboardBox.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/minileaderboard/MinileaderboardBox.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/minileaderboard/MinileaderboardBoxItem.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/minileaderboard/MinileaderboardBoxItem.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/minileaderboard/MinileaderboardBoxItemLegend.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/minileaderboard/MinileaderboardBoxItemLegend.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/quickfinder/Quickfinder.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/quickfinder/Quickfinder.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecent.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecent.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecent.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecentResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecentYear.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecentYear.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecentYearEvent.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/recents/EventsOverviewRecentYearEvent.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatus.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatus.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatus.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatusRace.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatusRace.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatusRegatta.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatusRegatta.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattaStatus/RegattaStatusResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/section/IsMobileSection.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/section/MobileSection.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/section/MobileSection.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/section/MobileSection.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/section/MobileSectionResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/sectionHeader/SectionHeader.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/sectionHeader/SectionHeader.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/sectionHeader/SectionHeaderContent.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/sectionHeader/SectionHeaderContent.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/sectionHeader/SectionHeaderResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/seriesheader/SeriesHeader.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/seriesheader/SeriesHeader.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/seriesheader/SeriesHeader.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/seriesheader/SeriesHeaderResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/simpleinfoblock/SimpleInfoBlock.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/simpleinfoblock/SimpleInfoBlock.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/socialfooter/SocialFooter.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/socialfooter/SocialFooter.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/socialfooter/SocialFooterResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/statisticsBox/StatisticsBox.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/statisticsBox/StatisticsBox.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/statisticsBox/StatisticsBox.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/statisticsBox/StatisticsBoxItem.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/statisticsBox/StatisticsBoxItem.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/statisticsBox/StatisticsBoxResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/toggleButton/ToggleButton.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/toggleButton/ToggleButton.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/toggleButton/ToggleButton.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/toggleButton/ToggleButtonResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/upcoming/EventsOverviewUpcoming.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/upcoming/EventsOverviewUpcoming.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/upcoming/EventsOverviewUpcoming.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/upcoming/EventsOverviewUpcomingEvent.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/upcoming/EventsOverviewUpcomingEvent.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/upcoming/EventsOverviewUpcomingResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/updatesBox/NewsItemLinkProvider.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/updatesBox/UpdatesBox.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/updatesBox/UpdatesBox.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/updatesBox/UpdatesBox.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/updatesBox/UpdatesBoxItem.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/updatesBox/UpdatesBoxItem.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/updatesBox/UpdatesBoxResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/MainView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/QuickfinderPresenter.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/RegattaLeaderboardNavigationProvider.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/SeriesLeaderboardNavigationProvider.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/EventActivity.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/EventActivityProxy.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/EventView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/EventViewImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/EventViewImpl.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/overview/EventOverviewStage.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/event/overview/EventOverviewStage.ui.xml delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/events/EventsActivity.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/events/EventsActivityProxy.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/events/EventsView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/events/EventsViewImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/events/EventsViewImpl.ui.xml delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/latestnews/LatestNewsActivity.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/latestnews/LatestNewsActivityProxy.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/latestnews/LatestNewsPlace.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/latestnews/LatestNewsView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/latestnews/LatestNewsViewImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/latestnews/LatestNewsViewImpl.ui.xml delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/minileaderboard/MiniLeaderboardActivity.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/minileaderboard/MiniLeaderboardActivityProxy.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/minileaderboard/MiniLeaderboardPlace.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/minileaderboard/MiniLeaderboardView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/minileaderboard/MiniLeaderboardViewImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/minileaderboard/MiniLeaderboardViewImpl.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/OverallLeaderboardNavigationProvider.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/SeriesActivity.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/SeriesActivityProxy.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/SeriesView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/SeriesViewImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/SeriesViewImpl.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/minileaderboard/SeriesMiniOverallLeaderboardActivity.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/minileaderboard/SeriesMiniOverallLeaderboardActivityProxy.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/minileaderboard/SeriesMiniOverallLeaderboardPlace.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/minileaderboard/SeriesMiniOverallLeaderboardView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/minileaderboard/SeriesMiniOverallLeaderboardViewImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/series/minileaderboard/SeriesMiniOverallLeaderboardViewImpl.ui.xml delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/start/StartActivity.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/start/StartActivityProxy.java delete mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/start/StartView.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/start/StartViewImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/places/start/StartViewImpl.ui.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/resources/SharedResources.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/resources/css/main.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/resources/css/media.gss delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/SwitchingEntryPoint.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/app/ApplicationPlaceUpdater.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/app/HasLocationTitle.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/app/HasMobileVersion.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/dispatch/DispatchSystem.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/dispatch/DispatchSystemImpl.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/utils/LogoUtil.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/regattaoverview/SourceRegattaOverview.gwt.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/CommonConfigs.gwt.xml create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/Sources.gwt.xml create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaImportDialog.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/media/PauseEvent.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/media/PlayEvent.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ViewerToolbar.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/ServerDispatchException.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/EventActionUtil.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/EventStatisticsDTO.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/GetEventStatisticsAction.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/GetMiniLeaderboardDTO.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/GetMiniLeaderbordAction.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/GetMiniOverallLeaderbordAction.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/GetRegattasAndLiveRacesForEventAction.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/LeaderboardContext.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/MiniLeaderboardItemDTO.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RacesActionUtil.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/RegattasAndLiveRacesDTO.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/dispatch/event/SimpleCompetitorDTO.java delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/general/HasLogo.java create mode 100755 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/Home.gwt.xml delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/18FOOTER.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/CANOE_IC.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/CANOE_TAIFUN.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/D_ONE.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/FUN.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/J22.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/KIELZUGVOGEL.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/LASER2.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/O_JOLLE.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/RS_FEVA.png delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/TRIAS.png delete mode 100755 java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogEndOfTrackingEventDeserializer.java delete mode 100755 java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/racelog/impl/RaceLogStartOfTrackingEventDeserializer.java delete mode 100755 java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEndOfTrackingEventSerializer.java delete mode 100755 java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogStartOfTrackingEventSerializer.java delete mode 100644 java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/CommonControlCSS.gwt.xml delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/CommonControlCSS_Autoinject.gwt.xml delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/Highcharts.gwt.xml delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/Highcharts_Autoinject.gwt.xml delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/CommonControlsCSS.java delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/CommonControlsInjectingEntryPoint.java delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/Highcharts.java delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/HighchartsInjectingEntryPoint.java delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/LegacyResources.java delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/adapters/standalone-framework.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/adapters/standalone-framework.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/canvas-tools.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/canvas-tools.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/data.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/data.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/drilldown.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/drilldown.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/exporting.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/exporting.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/funnel.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/funnel.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/heatmap.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/heatmap.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/no-data-to-display.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/no-data-to-display.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/solid-gauge.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/modules/solid-gauge.src.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/dark-blue.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/dark-green.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/dark-unica.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/gray.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/grid-light.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/grid.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/sand-signika.js delete mode 100644 java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/themes/skies.js delete mode 100644 java/com.sap.sse.security.ui/.tmp/gwt-work/.gitignore delete mode 100644 wiki/smartphone-tracking.md diff --git a/configuration/sailing b/configuration/sailing index f62b001fa48..db49d09bf17 100755 --- a/configuration/sailing +++ b/configuration/sailing @@ -11,11 +11,7 @@ RETVAL=0 JAVA_START_INSTANCES="server" -SERVERS_DIR=/home/sailing/servers GIT_REPOSITORY=/home/sailing/code -APACHE_CONFIG_DIR=/etc/httpd/conf.d -rm /var/log/sailing.out -rm /var/log/sailing.err start_tmux() { su - sailing -c "/home/sailing/bin/tmuxConsole.sh unattended" @@ -28,28 +24,25 @@ start_servers() { echo "Using ${MEMORY_PER_INSTANCE_IN_MB}MB as default heap size per instance." for conf in $JAVA_START_INSTANCES; do echo "Checking for amazon update..." - echo "MEMORY=\"${MEMORY_PER_INSTANCE_IN_MB}m\"" >>$SERVERS_DIR/$conf/env.sh - su - sailing -c "cd $SERVERS_DIR/$conf && $GIT_REPOSITORY/java/target/refreshInstance.sh auto-install" 2>>/var/log/sailing.err >>/var/log/sailing.out + echo "MEMORY=\"${MEMORY_PER_INSTANCE_IN_MB}m\"" >>/home/sailing/servers/$conf/env.sh + su - sailing -c "cd /home/sailing/servers/$conf && $GIT_REPOSITORY/java/target/refreshInstance.sh auto-install" 2>/var/log/sailing.err >/var/log/sailing.out ( # execute env.sh in a subshell which now has the same set of variables that the server will see - source $SERVERS_DIR/$conf/env.sh + source /home/sailing/servers/$conf/env.sh + launch_httpd echo "Starting Java server $conf" - su - sailing -c "cd $SERVERS_DIR/$conf && ./start" 2>>/var/log/sailing.err >>/var/log/sailing.out - server_name="`echo $SERVER_NAME | tr [A-Z] [a-z]`" - echo "Appending macro invocation to $APACHE_CONFIR_DIR/001-events.conf to map ${server_name}.sapsailing.com to event with ID $EVENT_ID with server running on local port $SERVER_PORT..." >>/var/log/sailing.out - echo "Use Event $server_name.sapsailing.com \"$EVENT_ID\" 127.0.0.1 $SERVER_PORT" >>$APACHE_CONFIG_DIR/001-events.conf + su - sailing -c "cd /home/sailing/servers/$conf && ./start" 2>/var/log/sailing.err >/var/log/sailing.out # terminating the subshell will forget all the variable assignments brought in by env.sh, clearing for the next server instance ) RETVAL=$? [ $RETVAL -eq 0 ] && success || failure done - launch_httpd } stop_servers() { for conf in $JAVA_START_INSTANCES; do echo "Stopping Java server $conf" - su - sailing -c "cd $SERVERS_DIR/$conf && ./stop" + su - sailing -c "cd /home/sailing/servers/$conf && ./stop" RETVAL=$? [ $RETVAL -eq 0 ] && success || failure done @@ -57,17 +50,16 @@ stop_servers() { # launch_httpd(server_name, port, event_id) launch_httpd() { - echo "Will try to launch httpd so this replica can work with an ELB easily." >>/var/log/sailing.out - if [ -x /etc/init.d/httpd ]; then - FIRST_SERVER=`echo $JAVA_START_INSTANCES | awk '{print $1;}'` - source $SERVERS_DIR/$FIRST_SERVER/env.sh - # Append Apache macro invocation for /internal-server-status based on mod_status and INSTANCE_DNS to $APACHE_CONFIG_DIR/001-events.conf - echo "Appending macro usage for $INSTANCE_DNS/internal-server-status URL for mod_status based Apache monitoring to $APACHE_CONFIG_DIR/001-events.conf" >>/var/log/sailing.out - echo "Use Status $INSTANCE_DNS internal-server-status" >>$APACHE_CONFIG_DIR/001-events.conf - echo "Launching httpd..." >>/var/log/sailing.out - service httpd start - else - echo Can't launch httpd; start script doesn't seem to be installed at /etc/init.d/httpd + if [ "$REPLICATE_ON_START" != "" ]; then + echo "REPLICATE_ON_START is $REPLICATE_ON_START. Will try to launch httpd so this replica can work with an ELB easily." + if [ -x /etc/init.d/httpd ]; then + server_name="`echo $SERVER_NAME | tr [A-Z] [a-z]`" + echo "Use Event $server_name.sapsailing.com \"$EVENT_ID\" 127.0.0.1 $SERVER_PORT" >>/etc/httpd/conf.d/001-events.conf + echo "Launching httpd to map ${server_name}.sapsailing.com to event with ID $EVENT_ID with server running on local port $SERVER_PORT..." + service httpd start + else + echo Can't launch httpd; start script doesn't seem to be installed at /etc/init.d/httpd + fi fi } diff --git a/configuration/sailing.sh b/configuration/sailing.sh deleted file mode 100644 index 7efa3b8a5b7..00000000000 --- a/configuration/sailing.sh +++ /dev/null @@ -1,17 +0,0 @@ -# Script to be linked from /etc/profile.d -# Appends to PATH, sets DISPLAY for VNC running on :2, exports JAVA_HOME and Amazon EC2 variables - -ulimit -n 30000 -ulimit -u 40000 - -export EC2_HOME=/opt/amazon/ec2-api-tools-1.6.8.0 -export EC2_URL=https://ec2.eu-west-1.amazonaws.com -export JAVA_HOME=/opt/jdk1.8.0_45 -export JAVA_1_7_HOME=/opt/jdk1.7.0_75 - -export PATH=$PATH:$JAVA_HOME/bin:/opt/amazon/ec2-api-tools-1.6.8.0/bin:/opt/amazon/bin - -export DISPLAY=:2.0 - -alias sa='eval `ssh-agent`; ssh-add ~/.ssh/id_dsa' -alias ll="ls -lh --color" diff --git a/home.md b/home.md index cfcf36ddcb7..f6fca6bdba8 100644 --- a/home.md +++ b/home.md @@ -17,7 +17,7 @@ SAP is at the center of today’s technology revolution, developing innovations * [[Big Data - Numbers|wiki/big-data-numbers]] * [[Sailing Domain Algorithms|wiki/sailing-domain-algorithms]] * [[Inventory|wiki/inventar-liste]] - * [[RaceLog / Smartphone tracking|wiki/racelog-tracking]] + * [[RaceLog tracking|wiki/racelog-tracking]] * [[Racecommittee App|wiki/racecommittee-app]] * [[Tracking App|wiki/tracking-app]] * [[Web Services API|wiki/sailing-webservices]] diff --git a/java/CodeFormatter_IntelliJ.jar b/java/CodeFormatter_IntelliJ.jar index 1df4afba95626db8ea51b983eb3c2f2168d11edf..ae4484fa93db2d539edce77cf2c88f7b1691453a 100644 GIT binary patch delta 1139 zcmZn{p20ie^F%Iz$;^!6^$`dAZW##d{jM$WDw98AYSc<6%}JhnCQPz8VV3%GVVFpe z123cM!ngna_Bl7Ga(b^QyS?TVr{Txy$KP#?)iUm7y*hnk_HXa~g1fx`2Ty*SxcT$4 zix&zkdc(S3-Zi?ADCqx=dH!$DO&sYPtN66TUZ-s2GQQIxyt02sLC(oe0kyaFAJZN$ zm(F<*DU|ysjd|&o7d-3B(xX%V2uu@unOM8&`SfMBB{LM>Uro z{Ey;ybiBSMbYXZFaZ#Y}msy2tZhPNaCU)&e-`l3UyRA;`T{Hck`bOTg|2^e$3<2KK>>NGZ z3r_xIVqj1gX8;N?vxqQo0AWh;oXK<8jrESz4}mU-^IQbb%93lT;=eb^T#~`n*Wv;FQDS(GQseyxBQst~=y nOk50bQ{7++L9{F~hv5gy9Gcqt3vx0a4*iHES delta 1911 zcmaKtX;4#F7=|wf2(k$T&{B(vfha-8K@wkdnPOfp?nou&Z-!x7I=@t!8l&rN}1}drUr9f{6KG z@RnG1Vbb*5;HCHbYU7V*1q*)L$4wkv*;fk@P!HgMo%)$v$bm{LXsx_xaKzL^Y z60li?hLf%c?N>$Ibp~42JC%2&_kP~=@Nn%lJ2SW4dS$1^@1ZZ^JYc_em{V<4%b6mBcNY=@$!{B>ZqI>zYkW5Unk={KK*y-uR#i}3fnS<@mY@>6HR9V18m z;2I4L+>Cn2e$`|O#*DM&?~N>f{T&@VEkoWlnH4yT`m?r>00le;3{tI|dVIRmXNt)bZghVxz;O{)I-f8*$W&{u#sf+ zltm3c)O-u?^D2g{q-V{V+&@#R81C|?W!5;{3e@J9xCm4KZ_C2mS^J3t=~W9lQNX)353Y3 zU%T#`-%R)UrHsli$Ln*_4F|!P;LH>Yzwx_wf2iWTaMuqhIzq)IZnlcQIi0|x2fi_x za5{X^K5Z|9odzAkqC8b*o)y%1S$<2J6Lmf!<5Eom_A-B9PFsj7`4wgW>%c}!CtH0sT^FJSww+upC8qg4{sP5 zVoyKGw<%6L5p057f016tU&bZXuN&H0^~2_rDV&}X&>=jBt=Icui6!GT{0!8%?0y?^ z{*MiDNpMjq?A>2?pGMQgF1~KQM<}T0iIsM?7WiDjX9wsLL@gG<3xvU`A507 z%ey_=aJ|&xjvQbR7C~%NU|#|9q`Fms(uKvj5FxR3%`&~r^e=?_G8B)4DzLJjxD`ME zAVLQK@HmL9CZHf04>QaifgL4z2~fjmBq}A+#GeurK_vw_1d(Xeh)85iC^?FbQS3q~ z%Pw9`UV@5cEV-vNzJru)3}Ii>m2XYmtv<|e)5r=4K7W6^pd-+Q_f!z>S!jgxuWR z>+^uy5i|XHnAP&s7CE-ryruoI(D$dS(eWR4Ns)B#C#z>j0z+j00NiG(qka7mlkN^C z;y*CRKxzwl8{? z(yRuo3S({jf35gJrtkfhv7dheiUp(~sZV ztv8%)g+$1tMzJmAs78suC#kfTeIrf|$bENsFcMU{!Fcy!Xj5{9P=%8fww3h~xOvH= zvdy0tx5zM&)dg*`F^aoPl^xctp0n7g`15MH37xAs*g(XXg?^}I@l?&_O+o8Amcf`f z;rK_#Zc*FHxmP;AN1PwTT^J%XCRNvAhFvE7K-ZJ^m4@L#<|(5qe4covFJJkk_El!! zo?8N*dhw}*`*2mtGHB$ohK#L zVY_nWw)=b}2l$^IJDW-JI_@M<+3qA+(d7X^q7}`bOeO{)X)!eERz=`H)Q`0M?4zyj mPyoPEXhbrZDashboard + diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/resources/com/sap/sailing/dashboards/gwt/RibDashboard.gwt.xml b/java/com.sap.sailing.dashboards.gwt/src/main/resources/com/sap/sailing/dashboards/gwt/RibDashboard.gwt.xml index 23d12666089..9fb25ff0c7a 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/resources/com/sap/sailing/dashboards/gwt/RibDashboard.gwt.xml +++ b/java/com.sap.sailing.dashboards.gwt/src/main/resources/com/sap/sailing/dashboards/gwt/RibDashboard.gwt.xml @@ -31,7 +31,8 @@ - + + diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java index 6f8be9c57b8..b317e1aa2a5 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/AbstractPosition.java @@ -145,20 +145,14 @@ public class AbstractPosition implements Position { @Override public Distance alongTrackDistance(Position from, Bearing bearing) { - final Distance result; - if (from != null && bearing != null) { - double direction = Math.signum(Math.cos(from.getBearingGreatCircle(this).getRadians() - bearing.getRadians())); - // Test if denominator gets ridiculously small; if so, the cross-track error is about 90� central angle. - // This means that the cross-track error is maximized, and that there is no way to determine how far along - // the great circle described by pos2 and bearing we should travel. This is an exception which will - // surface as a division-by-zero exception or a NaN result - result = new CentralAngleDistance(direction - * Math.acos(Math.cos(from.getCentralAngleRad(this)) - / Math.cos(crossTrackError(from, bearing).getCentralAngleRad()))); - } else { - result = null; - } - return result; + double direction = Math.signum(Math.cos(from.getBearingGreatCircle(this).getRadians() - bearing.getRadians())); + // Test if denominator gets ridiculously small; if so, the cross-track error is about 90� central angle. + // This means that the cross-track error is maximized, and that there is no way to determine how far along + // the great circle described by pos2 and bearing we should travel. This is an exception which will + // surface as a division-by-zero exception or a NaN result + return new CentralAngleDistance(direction + * Math.acos(Math.cos(from.getCentralAngleRad(this)) + / Math.cos(crossTrackError(from, bearing).getCentralAngleRad()))); } @Override 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 7c42ded1317..e95c3198a40 100644 --- 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 @@ -4,7 +4,6 @@ import com.sap.sailing.domain.common.impl.MeterDistance; public enum BoatClassMasterdata { - _18Footer ("18Footer", true, 8.90, 2.00, BoatHullType.MONOHULL, true, "18.Footer", "18ft", "18ft Skiff"), _2_4M ("2.4 Meter", true, 4.11, 0.81, BoatHullType.MONOHULL, false, "2.4M", "2.4mR", "2.4 Metre", "2.4-metre"), _5O5 ("5O5", true, 5.03, 1.88, BoatHullType.MONOHULL, true, "505", "5o5", "505er", "5o5er"), _12M ("12 Meter", true, 5.97, 1.43, BoatHullType.MONOHULL, true, "12M", "12mR", "12SQM", "12-metre", "12 metre"), @@ -17,10 +16,7 @@ public enum BoatClassMasterdata { A_CAT ("A-Catamaran", true, 5.49, 2.30, BoatHullType.CATAMARAN, false, "A-Cat", "ACat", "A-Class Catamaran"), ALBIN_EXPRESS ("Albin Express", true, 7.77, 2.50, BoatHullType.MONOHULL, false), ALBIN_BALLAD ("Albin Ballad", true, 9.12, 2.95, BoatHullType.MONOHULL, false), - CANOE_IC ("International Canoe", true, 5.20, 1.01, BoatHullType.MONOHULL, true, "Canoe IC", "Canoe-IC", "IC", "Kanu IC", "International Canoe", "International 10 Sq.m. Sailing Canoe"), - CANOE_TAIFUN ("Canoe Taifun", true, 5.20, 1.32, BoatHullType.MONOHULL, false, "Taifun", "Taifun Kanu", "Kanu Taifun"), B_ONE ("B/ONE", true, 7.80, 2.49, BoatHullType.MONOHULL, true, "B-ONE"), - D_ONE ("D-One", true, 4.23, 2.31, BoatHullType.MONOHULL, true, "Devoti D-One", "DOne", "D_One"), DRAGON_INT ("Dragon Int.", true, 8.89, 1.96, BoatHullType.MONOHULL, true, "Drachen", "Dragon"), EXTREME_40 ("Extreme 40", false, 12.2, 6.60, BoatHullType.CATAMARAN, true, "Extreme-40", "Extreme40", "ESS40"), D_35 ("D35", false, 10.81, 6.89, BoatHullType.CATAMARAN, false), @@ -29,21 +25,16 @@ public enum BoatClassMasterdata { F_18 ("Formula 18", true, 6.85, 2.25, BoatHullType.CATAMARAN, true, "F18", "F-18"), FARR_30 ("Farr 30", true, 9.42, 3.08, BoatHullType.MONOHULL, true, "F30", "F-30", "Farr-30"), FINN ("Finn", true, 4.50, 1.51, BoatHullType.MONOHULL, false), - FLYING_PHANTOM ("Flying Phantom", true, 5.52, 3.00, BoatHullType.CATAMARAN, true), FOLKBOAT ("Folkboat", true, 7.68, 2.20, BoatHullType.MONOHULL, false, "Folke", "Folkeboot"), - FUN ("FUN", true, 7.20, 2.45, BoatHullType.MONOHULL, true, "FUN O.D.", "FUN OD"), F_16 ("Formula 16", true, 5.00, 2.50, BoatHullType.CATAMARAN, true, "F16", "F-16"), HOBIE_16 ("Hobie 16", true, 5.05, 2.41, BoatHullType.CATAMARAN, false, "H16"), H_BOAT ("H-Boat", true, 8.28, 2.18, BoatHullType.MONOHULL, true, "HB"), HOBIE_TIGER ("Hobie Tiger", true, 5.51, 2.60, BoatHullType.CATAMARAN, true), HOBIE_WILD_CAT ("Hobie Wild Cat", true, 5.49, 2.59, BoatHullType.CATAMARAN, true, "Hobie Wild Cat F18"), - J22 ("J/22", true, 6.86, 2.44, BoatHullType.MONOHULL, true, "J22", "J-22"), - J24 ("J/24", true, 7.32, 2.67, BoatHullType.MONOHULL, true, "J24", "J-24"), J70 ("J/70", true, 6.93, 2.25, BoatHullType.MONOHULL, true, "J70", "J-70"), J80 ("J/80", true, 8.0, 2.51, BoatHullType.MONOHULL, true, "J80", "J-80"), - KIELZUGVOGEL ("Kielzugvogel", true, 5.80, 1.88, BoatHullType.MONOHULL, false), + J24 ("J/24", true, 7.32, 2.67, BoatHullType.MONOHULL, true, "J24", "J-24"), KITE ("Kite", true, 3.35, 1.52, BoatHullType.MONOHULL, false), - LASER_2 ("Laser 2", true, 4.39, 1.42, BoatHullType.MONOHULL, false, "Laser II", "Laser2", "Laser-2", "Laser-II"), LASER_4_7 ("Laser 4.7", true, 4.20, 1.39, BoatHullType.MONOHULL, false, "L4.7"), LASER_RADIAL ("Laser Radial", true, 4.19, 1.41, BoatHullType.MONOHULL, false, "LAR", "Laser RAD", "RAD", "Radial"), LASER_INT ("Laser Int.", true, 4.19, 1.39, BoatHullType.MONOHULL, false, "Laser", "LSR"), @@ -52,25 +43,22 @@ public enum BoatClassMasterdata { MINI_TRANSAT ("Mini Transat 6.50", true, 6.50, 3.00, BoatHullType.MONOHULL, true, "Mini Transat"), MUSTO_SKIFF ("Musto Skiff", true, 4.55, 1.35, BoatHullType.MONOHULL, true, "Musto Performance Skiff", "MPS", "Musto"), NACRA_17 ("Nacra 17", true, 5.25, 2.59, BoatHullType.CATAMARAN, true, "N17", "Nacra-17"), - O_JOLLE ("O-Jolle", true, 5.00, 1.66, BoatHullType.MONOHULL, false, "O Jolle", "OJolle", "Olympiajolle"), OK ("OK Dinghy", true, 5.25, 2.59, BoatHullType.MONOHULL, false, "OK-Dinghy", "OK-Jolle", "OK"), OPTIMIST ("Optimist", true, 2.34, 1.07, BoatHullType.MONOHULL, false, "Opti", "Optimist Dinghy"), PIRATE ("Pirate", true, 5.00, 1.61, BoatHullType.MONOHULL, false, "Pirat", "Piraten"), PLATU_25 ("Platu 25", true, 7.53, 2.62, BoatHullType.MONOHULL, true, "Platu", "Platu-25", "PLA", "B25"), RS_X ("RS:X", true, 2.86, 0.93, BoatHullType.SURFERBOARD, false, "RS-X", "RSX", "RS:X"), - RS_FEVA ("RS Feva", true, 3.64, 1.42, BoatHullType.MONOHULL, true, "RSFeva"), SONAR ("Sonar", true, 7.01, 2.39, BoatHullType.MONOHULL, true), STAR ("Star", true, 6.92, 1.74, BoatHullType.MONOHULL, false, "STR"), STREAMLINE ("Streamline", true, 7.15, 2.55, BoatHullType.MONOHULL, true), SWAN_45 ("Swan 45", true, 13.83, 3.91, BoatHullType.MONOHULL, true, "Swan", "Swan-45"), TORNADO ("Tornado Catamaran", true, 6.10, 3.02, BoatHullType.CATAMARAN, true, "Tornado", "Tornado Cat"), - TRIAS ("Trias", true, 9.20, 2.12, BoatHullType.MONOHULL, true), X_99 ("X-99", true, 9.96, 2.95, BoatHullType.MONOHULL, true, "X99"), CONTENDER ("Contender", true, 4.88, 1.42, BoatHullType.MONOHULL, false), RC44 ("RC44", true, 13.35, 2.75, BoatHullType.MONOHULL, true), FLYING_DUTCHMAN ("Flying Dutchman", true, 6.10, 1.80, BoatHullType.MONOHULL, true), DYAS("Dyas", true, 7.15, 1.95, BoatHullType.MONOHULL, true), - INTERNATIONAL_14("International 14", true, 4.27, 1.83, BoatHullType.MONOHULL, true, "I14", "Int.14", "Int14"), + INTERNATIONAL_14("International 14", true, 4.27, 1.83, BoatHullType.MONOHULL, true, "I14"), OPEN_BIC("O'pen BIC", true, 2.75, 1.14, BoatHullType.MONOHULL, false, "OpenBIC"), // multi-class "boat classes"; to be replaced at some later point in time by something like a RegattaClass diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/FleetColors.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/FleetColors.java index d09a58fed61..5388a820a86 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/FleetColors.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/FleetColors.java @@ -11,10 +11,7 @@ public enum FleetColors { BLUE (39, 140, 194, 0), YELLOW (251,186,0, 0), GREEN (138, 181, 78, 0), - RED (232, 74, 26, 0), - PURPLE (212, 28, 175, 0), - NEON_GREEN (118, 255, 33, 0), - ORANGE (255, 174, 23, 0); + RED (232, 74, 26, 0); private Color color; diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java index b25873ad0c1..743a32d9f2d 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/Position.java @@ -57,13 +57,11 @@ public interface Position extends Serializable { Distance crossTrackError(Position p, Bearing bearing); /** - * Computes how far along the great circle starting at from and pointing to bearing one - * has to travel to reach the projection of this position onto the great circle described by from and - * bearing. Note that if the angle between this position and the great circle is 90 degrees then there - * is no solution, and a NaN or exception will result. - *

- * - * If either from or bearing or both are null, null is returned. + * Computes how far along the great circle starting at from and pointing + * to bearing one has to travel to reach the projection of this position + * onto the great circle described by from and bearing. Note that + * if the angle between this position and the great circle is 90 degrees then there is + * no solution, and a NaN or exception will result. */ Distance alongTrackDistance(Position from, Bearing bearing); diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java index f77fb9b316f..571fb5245b7 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java @@ -35,7 +35,7 @@ import com.mongodb.util.JSON; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl; import com.sap.sailing.domain.abstractlog.race.CompetitorResults; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; @@ -55,7 +55,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultsImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl; import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl; @@ -1047,14 +1047,6 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { logger.severe("Error parsing official website URL "+officialWebSiteURLAsString+" for event "+name+". Ignoring this URL."); } } - String sailorsInfoWebSiteURLAsString = (String) eventDBObject.get(FieldNames.EVENT_SAILORS_INFO_WEBSITE_URL.name()); - if (sailorsInfoWebSiteURLAsString != null) { - try { - result.setSailorsInfoWebsiteURL(new URL(sailorsInfoWebSiteURLAsString)); - } catch (MalformedURLException e) { - logger.severe("Error parsing sailors info website URL "+sailorsInfoWebSiteURLAsString+" for event "+name+". Ignoring this URL."); - } - } BasicDBList images = (BasicDBList) eventDBObject.get(FieldNames.EVENT_IMAGES.name()); if (images != null) { for (Object imageObject : images) { @@ -1404,9 +1396,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { return loadRaceLogCloseOpenEndedDeviceMappingEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); } else if (eventClass.equals(RaceLogAdditionalScoringInformationEvent.class.getSimpleName())) { return loadRaceLogAdditionalScoringInformationEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); - } else if (eventClass.equals(RaceLogFixedMarkPassingEvent.class.getSimpleName())){ + } else if (eventClass.equals(FixedMarkPassingEvent.class.getSimpleName())){ return loadRaceLogFixedMarkPassingEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); - } else if (eventClass.equals(RaceLogSuppressedMarkPassingsEvent.class.getSimpleName())){ + } else if (eventClass.equals(SuppressedMarkPassingsEvent.class.getSimpleName())){ return loadRaceLogSuppressedMarkPassingsEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); } diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java index fc4fd028e43..32c758d91f8 100755 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java @@ -22,7 +22,6 @@ public enum FieldNames { EVENT_IMAGES, EVENT_VIDEOS, EVENT_OFFICIAL_WEBSITE_URL, - EVENT_SAILORS_INFO_WEBSITE_URL, EVENT_LOGO_IMAGE_URL, REGATTA_NAME, diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java index 2b7e479bcba..b896a058b5b 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java @@ -19,8 +19,7 @@ import com.mongodb.DBObject; import com.mongodb.WriteConcern; import com.mongodb.util.JSON; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; @@ -34,11 +33,10 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDefineMarkEvent; @@ -536,7 +534,6 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { eventDBObject.put(FieldNames.EVENT_ID.name(), event.getId()); eventDBObject.put(FieldNames.EVENT_LOGO_IMAGE_URL.name(), event.getLogoImageURL() != null ? event.getLogoImageURL().toString() : null); eventDBObject.put(FieldNames.EVENT_OFFICIAL_WEBSITE_URL.name(), event.getOfficialWebsiteURL() != null ? event.getOfficialWebsiteURL().toString() : null); - eventDBObject.put(FieldNames.EVENT_SAILORS_INFO_WEBSITE_URL.name(), event.getSailorsInfoWebsiteURL() != null ? event.getSailorsInfoWebsiteURL().toString() : null); storeTimePoint(event.getStartDate(), eventDBObject, FieldNames.EVENT_START_DATE); storeTimePoint(event.getEndDate(), eventDBObject, FieldNames.EVENT_END_DATE); eventDBObject.put(FieldNames.EVENT_IS_PUBLIC.name(), event.isPublic()); @@ -887,20 +884,6 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { return result; } - public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogEndOfTrackingEvent event) { - BasicDBObject result = new BasicDBObject(); - storeRaceLogIdentifier(raceLogIdentifier, result); - result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogEndOfTrackingEvent(event)); - return result; - } - - public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartOfTrackingEvent event) { - BasicDBObject result = new BasicDBObject(); - storeRaceLogIdentifier(raceLogIdentifier, result); - result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartOfTrackingEvent(event)); - return result; - } - public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogAdditionalScoringInformationEvent event) { BasicDBObject result = new BasicDBObject(); storeRaceLogIdentifier(raceLogIdentifier, result); @@ -916,14 +899,14 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { return result; } - public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFixedMarkPassingEvent event) { + public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, FixedMarkPassingEvent event) { BasicDBObject result = new BasicDBObject(); storeRaceLogIdentifier(raceLogIdentifier, result); result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFixedMarkPassingEvent(event)); return result; } - public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogSuppressedMarkPassingsEvent event) { + public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, SuppressedMarkPassingsEvent event) { BasicDBObject result = new BasicDBObject(); storeRaceLogIdentifier(raceLogIdentifier, result); result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogSuppressedMarkPassingsEvent(event)); @@ -946,20 +929,6 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { return result; } - private Object storeRaceLogEndOfTrackingEvent(RaceLogEndOfTrackingEvent event) { - DBObject result = new BasicDBObject(); - storeRaceLogEventProperties(event, result); - result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogEndOfTrackingEvent.class.getSimpleName()); - return result; - } - - private Object storeRaceLogStartOfTrackingEvent(RaceLogStartOfTrackingEvent event) { - DBObject result = new BasicDBObject(); - storeRaceLogEventProperties(event, result); - result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogStartOfTrackingEvent.class.getSimpleName()); - return result; - } - private Object storeRaceLogStartProcedureChangedEvent(RaceLogStartProcedureChangedEvent event) { DBObject result = new BasicDBObject(); storeRaceLogEventProperties(event, result); @@ -1061,19 +1030,19 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { return result; } - private Object storeRaceLogFixedMarkPassingEvent(RaceLogFixedMarkPassingEvent event) { + private Object storeRaceLogFixedMarkPassingEvent(FixedMarkPassingEvent event) { DBObject result = new BasicDBObject(); storeRaceLogEventProperties(event, result); - result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogFixedMarkPassingEvent.class.getSimpleName()); + result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), FixedMarkPassingEvent.class.getSimpleName()); result.put(FieldNames.INDEX_OF_PASSED_WAYPOINT.name(), event.getZeroBasedIndexOfPassedWaypoint()); result.put(FieldNames.TIMEPOINT_OF_FIXED_MARKPASSING.name(), event.getTimePointOfFixedPassing().asMillis()); return result; } - private Object storeRaceLogSuppressedMarkPassingsEvent(RaceLogSuppressedMarkPassingsEvent event) { + private Object storeRaceLogSuppressedMarkPassingsEvent(SuppressedMarkPassingsEvent event) { DBObject result = new BasicDBObject(); storeRaceLogEventProperties(event, result); - result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogSuppressedMarkPassingsEvent.class.getSimpleName()); + result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), SuppressedMarkPassingsEvent.class.getSimpleName()); result.put(FieldNames.INDEX_OF_FIRST_SUPPRESSED_WAYPOINT.name(), event.getZeroBasedIndexOfFirstSuppressedWaypoint()); return result; } @@ -1290,7 +1259,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { logger.info("Removing persistent competitor info for competitor "+competitor.getName()+" with ID "+competitor.getId()); DBCollection collection = database.getCollection(CollectionNames.COMPETITORS.name()); DBObject query = (DBObject) JSON.parse(CompetitorJsonSerializer.getCompetitorIdQuery(competitor).toString()); - collection.remove(query, WriteConcern.SAFE); + collection.remove(query); } @Override diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java index 0347f39f532..cef51870f44 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java @@ -3,8 +3,7 @@ package com.sap.sailing.domain.persistence.impl; import java.util.logging.Logger; import com.mongodb.DBObject; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; @@ -18,11 +17,10 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDefineMarkEvent; @@ -180,13 +178,13 @@ public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor { } @Override - public void visit(RaceLogFixedMarkPassingEvent event) { + public void visit(FixedMarkPassingEvent event) { DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); mongoObjectFactory.storeRaceLogEventEvent(object); } @Override - public void visit(RaceLogSuppressedMarkPassingsEvent event) { + public void visit(SuppressedMarkPassingsEvent event) { DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); mongoObjectFactory.storeRaceLogEventEvent(object); } @@ -196,18 +194,4 @@ public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor { DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); mongoObjectFactory.storeRaceLogEventEvent(object); } - - @Override - public void visit(RaceLogStartOfTrackingEvent event) { - DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); - mongoObjectFactory.storeRaceLogEventEvent(object); - - } - - @Override - public void visit(RaceLogEndOfTrackingEvent event) { - DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); - mongoObjectFactory.storeRaceLogEventEvent(object); - - } } diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java index 6dada58742b..55ed7d8088d 100755 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java @@ -18,9 +18,7 @@ import com.sap.sailing.domain.abstractlog.MultiLogAnalyzer.MapWithValueCollectio import com.sap.sailing.domain.abstractlog.MultiLogAnalyzer.SetReducer; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor; @@ -145,14 +143,6 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener { public void visit(RaceLogCourseDesignChangedEvent event) { RaceLogRaceTracker.this.onCourseDesignChangedEvent(event); } - @Override - public void visit(RaceLogStartOfTrackingEvent event) { - RaceLogRaceTracker.this.onStartOfTrackingEvent(event); - } - @Override - public void visit(RaceLogEndOfTrackingEvent event) { - RaceLogRaceTracker.this.onEndOfTrackingEvent(event); - } }; visitors.put(log, visitor); ((RaceLog) log).addListener(visitor); @@ -399,27 +389,22 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener { startTracking(event); } } - - private void onStartOfTrackingEvent(RaceLogStartOfTrackingEvent event) { - trackedRace.setStartOfTrackingReceived(event.getLogicalTimePoint()); - } - - private void onEndOfTrackingEvent(RaceLogEndOfTrackingEvent event) { - trackedRace.setEndOfTrackingReceived(event.getLogicalTimePoint()); - } private void onCourseDesignChangedEvent(RaceLogCourseDesignChangedEvent event) { - if (trackedRace != null) { - CourseBase base = new LastPublishedCourseDesignFinder(params.getRaceLog()).analyze(); - List> update = new ArrayList<>(); - for (Waypoint waypoint : base.getWaypoints()) { - update.add(new Util.Pair<>(waypoint.getControlPoint(), waypoint.getPassingInstructions())); - } - try { - trackedRace.getRace().getCourse().update(update, params.getDomainFactory()); - } catch (PatchFailedException e) { - logger.log(Level.WARNING, "Could not update course for race " + trackedRace.getRace().getName()); - } + if (trackedRace == null) + return; + + CourseBase base = new LastPublishedCourseDesignFinder(params.getRaceLog()).analyze(); + List> update = new ArrayList<>(); + + for (Waypoint waypoint : base.getWaypoints()) { + update.add(new Util.Pair<>(waypoint.getControlPoint(), waypoint.getPassingInstructions())); + } + + try { + trackedRace.getRace().getCourse().update(update, params.getDomainFactory()); + } catch (PatchFailedException e) { + logger.log(Level.WARNING, "Could not update course for race " + trackedRace.getRace().getName()); } } 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 99937e4f81a..ab2ae82adff 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 @@ -4,15 +4,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import java.util.UUID; - import org.junit.Before; import org.junit.Test; @@ -21,7 +18,6 @@ import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; -import com.sap.sailing.domain.abstractlog.race.impl.RaceLogFlagEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl; import com.sap.sailing.domain.abstractlog.race.state.RaceState; @@ -129,18 +125,7 @@ public class RaceStateTest { verify(listener).onStatusChanged(state); verifyNoMoreInteractions(listener); } - - /** - * See bug 3086: make sure that race log change events cause an update of the RacingProcedure - */ - @Test - public void testSetIndividualRecall() { - assertFalse(state.getRacingProcedure().isIndividualRecallDisplayed()); - raceLog.add(new RaceLogFlagEventImpl(MillisecondsTimePoint.now(), author, MillisecondsTimePoint.now(), UUID - .randomUUID(), null, /* pass */0, Flags.XRAY, Flags.NONE, /* pIsDisplayed */true)); - assertTrue(state.getRacingProcedure().isIndividualRecallDisplayed()); - } - + @Test public void testAdvancePass() { state.addChangedListener(listener); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/CompetitorResults.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/CompetitorResults.java index 0cd9baf9035..624672b9710 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/CompetitorResults.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/CompetitorResults.java @@ -6,10 +6,6 @@ import java.util.List; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sse.common.Util; -/** - * A triple holding the competitor ID, the competitor name and the {@link MaxPointReason} documenting the score for the - * competitor - */ public interface CompetitorResults extends List> { } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogFixedMarkPassingEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/FixedMarkPassingEvent.java similarity index 73% rename from java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogFixedMarkPassingEvent.java rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/FixedMarkPassingEvent.java index c828e027965..097234c765e 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogFixedMarkPassingEvent.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/FixedMarkPassingEvent.java @@ -3,7 +3,7 @@ package com.sap.sailing.domain.abstractlog.race; import com.sap.sailing.domain.abstractlog.Revokable; import com.sap.sse.common.TimePoint; -public interface RaceLogFixedMarkPassingEvent extends RaceLogEvent, Revokable { +public interface FixedMarkPassingEvent extends RaceLogEvent, Revokable { public TimePoint getTimePointOfFixedPassing(); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEndOfTrackingEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEndOfTrackingEvent.java deleted file mode 100755 index c3811c991b7..00000000000 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEndOfTrackingEvent.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.sap.sailing.domain.abstractlog.race; - - -public interface RaceLogEndOfTrackingEvent extends RaceLogEvent { - -} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventFactory.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventFactory.java index 432f6690b41..32921542ad9 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventFactory.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventFactory.java @@ -122,13 +122,13 @@ public interface RaceLogEventFactory { RaceLogCloseOpenEndedDeviceMappingEvent createCloseOpenEndedDeviceMappingEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, int passId, Serializable deviceMappingEventId, TimePoint closingTimePoint); - RaceLogFixedMarkPassingEvent createFixedMarkPassingEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, + RaceLogEvent createFixedMarkPassingEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, List competitors, Integer passId, TimePoint ofFixedPassing, Integer zeroBasedIndexOfWaypoint); RaceLogAdditionalScoringInformationEvent createAdditionalScoringInformationEvent(TimePoint timePoint, Serializable id, AbstractLogEventAuthor author, int currentPassId, AdditionalScoringInformationType informationType); - RaceLogSuppressedMarkPassingsEvent createSuppressedMarkPassingsEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, + RaceLogEvent createSuppressedMarkPassingsEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, List competitors, Integer passId, Integer zeroBasedIndexOfFirstSuppressedWaypoint); RaceLogDependentStartTimeEvent createDependentStartTimeEvent(TimePoint logicalTimePoint, @@ -137,12 +137,4 @@ public interface RaceLogEventFactory { RaceLogDependentStartTimeEvent createDependentStartTimeEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, int passId, SimpleRaceLogIdentifier dependentOnRace, Duration startTimeDifference); - - RaceLogStartOfTrackingEvent createStartOfTrackingEvent(TimePoint startOfTracking, AbstractLogEventAuthor author, - Serializable id, List competitors, Integer passId); - - RaceLogEndOfTrackingEvent createEndOfTrackingEvent(TimePoint endOfTracking, AbstractLogEventAuthor author, - Serializable id, List competitors, Integer passId); - - } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java index 77174f3ac21..7ecbaac939e 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java @@ -55,13 +55,9 @@ public interface RaceLogEventVisitor { public void visit(RaceLogAdditionalScoringInformationEvent additionalScoringInformation); - public void visit(RaceLogFixedMarkPassingEvent event); + public void visit(FixedMarkPassingEvent event); - public void visit(RaceLogSuppressedMarkPassingsEvent event); + public void visit(SuppressedMarkPassingsEvent event); public void visit(RaceLogDependentStartTimeEvent event); - - public void visit(RaceLogStartOfTrackingEvent event); - - public void visit(RaceLogEndOfTrackingEvent event); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogStartOfTrackingEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogStartOfTrackingEvent.java deleted file mode 100755 index db3e9cce334..00000000000 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogStartOfTrackingEvent.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.sap.sailing.domain.abstractlog.race; - -public interface RaceLogStartOfTrackingEvent extends RaceLogEvent { - -} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogSuppressedMarkPassingsEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/SuppressedMarkPassingsEvent.java similarity index 65% rename from java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogSuppressedMarkPassingsEvent.java rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/SuppressedMarkPassingsEvent.java index 9b798a04b1d..e3d55cf6ec9 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogSuppressedMarkPassingsEvent.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/SuppressedMarkPassingsEvent.java @@ -2,7 +2,7 @@ package com.sap.sailing.domain.abstractlog.race; import com.sap.sailing.domain.abstractlog.Revokable; -public interface RaceLogSuppressedMarkPassingsEvent extends RaceLogEvent, Revokable { +public interface SuppressedMarkPassingsEvent extends RaceLogEvent, Revokable { public Integer getZeroBasedIndexOfFirstSuppressedWaypoint(); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/MarkPassingDataFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/MarkPassingDataFinder.java index edfc7a1d45a..e92650b50af 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/MarkPassingDataFinder.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/analyzing/impl/MarkPassingDataFinder.java @@ -3,10 +3,10 @@ package com.sap.sailing.domain.abstractlog.race.analyzing.impl; import java.util.HashSet; import java.util.Set; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.base.Competitor; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util.Triple; @@ -21,12 +21,12 @@ public class MarkPassingDataFinder extends RaceLogAnalyzer> performAnalysis() { Set> result = new HashSet>(); for (RaceLogEvent event : getLog().getUnrevokedEvents()) { - if (event instanceof RaceLogFixedMarkPassingEvent) { - RaceLogFixedMarkPassingEvent castedEvent = (RaceLogFixedMarkPassingEvent) event; + if (event instanceof FixedMarkPassingEvent) { + FixedMarkPassingEvent castedEvent = (FixedMarkPassingEvent) event; result.add(new Triple(castedEvent.getInvolvedBoats().get(0), castedEvent .getZeroBasedIndexOfPassedWaypoint(), castedEvent.getTimePointOfFixedPassing())); - } else if (event instanceof RaceLogSuppressedMarkPassingsEvent){ - RaceLogSuppressedMarkPassingsEvent castedEvent = (RaceLogSuppressedMarkPassingsEvent) event; + } else if (event instanceof SuppressedMarkPassingsEvent){ + SuppressedMarkPassingsEvent castedEvent = (SuppressedMarkPassingsEvent) event; result.add(new Triple(castedEvent.getInvolvedBoats().get(0), castedEvent.getZeroBasedIndexOfFirstSuppressedWaypoint(), null)); } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java index d042544fb76..856f15c45d2 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java @@ -1,14 +1,13 @@ package com.sap.sailing.domain.abstractlog.race.impl; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningConfirmedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningListChangedEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogGateLineOpeningTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent; @@ -16,11 +15,10 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDefineMarkEvent; @@ -138,12 +136,12 @@ public abstract class AbstractRaceLogChangedVisitor implements RaceLogEventVisit } @Override - public void visit(RaceLogFixedMarkPassingEvent fixedMarkPassingEvent) { + public void visit(FixedMarkPassingEvent fixedMarkPassingEvent) { notifyListenerAboutEventAdded(fixedMarkPassingEvent); } @Override - public void visit(RaceLogSuppressedMarkPassingsEvent event) { + public void visit(SuppressedMarkPassingsEvent event) { notifyListenerAboutEventAdded(event); } @@ -151,14 +149,4 @@ public abstract class AbstractRaceLogChangedVisitor implements RaceLogEventVisit public void visit(RaceLogDependentStartTimeEvent event) { notifyListenerAboutEventAdded(event); } - - @Override - public void visit(RaceLogStartOfTrackingEvent event) { - notifyListenerAboutEventAdded(event); - } - - @Override - public void visit(RaceLogEndOfTrackingEvent event) { - notifyListenerAboutEventAdded(event); - } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java index f0aed5f9999..8f20f90261c 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.abstractlog.race.impl; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; @@ -15,11 +14,10 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDefineMarkEvent; @@ -145,12 +143,12 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor { } @Override - public void visit(RaceLogFixedMarkPassingEvent event){ + public void visit(FixedMarkPassingEvent event){ } @Override - public void visit(RaceLogSuppressedMarkPassingsEvent event) { + public void visit(SuppressedMarkPassingsEvent event) { } @@ -158,14 +156,4 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor { public void visit(RaceLogDependentStartTimeEvent event) { } - - @Override - public void visit(RaceLogEndOfTrackingEvent event) { - - } - - @Override - public void visit(RaceLogStartOfTrackingEvent event) { - - } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogFixedMarkPassingEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/FixedMarkPassingEventImpl.java similarity index 79% rename from java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogFixedMarkPassingEventImpl.java rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/FixedMarkPassingEventImpl.java index 71b6978ac43..a981c8955b9 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogFixedMarkPassingEventImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/FixedMarkPassingEventImpl.java @@ -4,19 +4,19 @@ import java.io.Serializable; import java.util.List; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; import com.sap.sailing.domain.base.Competitor; import com.sap.sse.common.TimePoint; -public class RaceLogFixedMarkPassingEventImpl extends RaceLogEventImpl implements RaceLogFixedMarkPassingEvent { +public class FixedMarkPassingEventImpl extends RaceLogEventImpl implements FixedMarkPassingEvent { private final Integer zeroBasedIndexOfWaypointOfPassing; private final TimePoint timePointOfPassing; - public RaceLogFixedMarkPassingEventImpl(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, + public FixedMarkPassingEventImpl(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable pId, List pInvolvedBoats, int pPassId, TimePoint timePoint, Integer zeroBasedIndexOfWaypointOfPassing) { super(createdAt, author, logicalTimePoint, pId, pInvolvedBoats, pPassId); this.timePointOfPassing = timePoint; diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogChangedVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogChangedVisitor.java index 20be43cded1..42d6b95525e 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogChangedVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogChangedVisitor.java @@ -3,12 +3,6 @@ package com.sap.sailing.domain.abstractlog.race.impl; import com.sap.sailing.domain.abstractlog.race.RaceLogChangedListener; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; -/** - * Forwards events received by this visitor to the listener passed to the constructor. - * - * @author Axel Uhl (D043530) - * - */ public class RaceLogChangedVisitor extends AbstractRaceLogChangedVisitor { private final RaceLogChangedListener listener; diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEndOfTrackingEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEndOfTrackingEventImpl.java deleted file mode 100755 index 4199520a8b9..00000000000 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEndOfTrackingEventImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sap.sailing.domain.abstractlog.race.impl; - -import java.io.Serializable; -import java.util.List; - -import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; -import com.sap.sailing.domain.base.Competitor; -import com.sap.sse.common.TimePoint; - -public class RaceLogEndOfTrackingEventImpl extends RaceLogEventImpl implements RaceLogEndOfTrackingEvent { - private static final long serialVersionUID = 3130293807404190473L; - - public RaceLogEndOfTrackingEventImpl(TimePoint createdAt, AbstractLogEventAuthor author, - TimePoint endOfTracking, Serializable pId, List pInvolvedBoats, int pPassId) { - super(createdAt, author, endOfTracking, pId, pInvolvedBoats, pPassId); - - } - - @Override - public void accept(RaceLogEventVisitor visitor) { - visitor.visit(this); - - } -} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEventFactoryImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEventFactoryImpl.java index 86646bee693..995dec41bf9 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEventFactoryImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogEventFactoryImpl.java @@ -11,11 +11,9 @@ import com.sap.sailing.domain.abstractlog.race.CompetitorResults; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory; import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningConfirmedEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogGateLineOpeningTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent; @@ -23,10 +21,8 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformationType; @@ -302,28 +298,16 @@ public class RaceLogEventFactoryImpl implements RaceLogEventFactory { } @Override - public RaceLogFixedMarkPassingEvent createFixedMarkPassingEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, + public RaceLogEvent createFixedMarkPassingEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, List competitors, Integer passId, TimePoint ofFixedPassing, Integer zeroBasedIndexOfWaypoint) { - return new RaceLogFixedMarkPassingEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, id, competitors, passId, ofFixedPassing, + return new FixedMarkPassingEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, id, competitors, passId, ofFixedPassing, zeroBasedIndexOfWaypoint); } @Override - public RaceLogSuppressedMarkPassingsEvent createSuppressedMarkPassingsEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, + public RaceLogEvent createSuppressedMarkPassingsEvent(TimePoint logicalTimePoint, AbstractLogEventAuthor author, Serializable id, List competitors, Integer passId, Integer zeroBasedIndexOfFirstSuppressedWaypoint) { - return new RaceLogSuppressedMarkPassingsEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, id, competitors, passId, + return new SuppressedMarkPassingsEventImpl(MillisecondsTimePoint.now(), author, logicalTimePoint, id, competitors, passId, zeroBasedIndexOfFirstSuppressedWaypoint); } - - @Override - public RaceLogStartOfTrackingEvent createStartOfTrackingEvent(TimePoint startOfTracking, AbstractLogEventAuthor author, Serializable id, - List competitors, Integer passId) { - return new RaceLogStartOfTrackingEventImpl(MillisecondsTimePoint.now(), author, startOfTracking, id, competitors, passId); - } - - @Override - public RaceLogEndOfTrackingEvent createEndOfTrackingEvent(TimePoint endOfTracking, AbstractLogEventAuthor author, Serializable id, - List competitors, Integer passId) { - return new RaceLogEndOfTrackingEventImpl(MillisecondsTimePoint.now(), author, endOfTracking, id, competitors, passId); - } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogStartOfTrackingEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogStartOfTrackingEventImpl.java deleted file mode 100755 index a8cadf7c118..00000000000 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogStartOfTrackingEventImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sap.sailing.domain.abstractlog.race.impl; - -import java.io.Serializable; -import java.util.List; - -import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; -import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; -import com.sap.sailing.domain.base.Competitor; -import com.sap.sse.common.TimePoint; - -public class RaceLogStartOfTrackingEventImpl extends RaceLogEventImpl implements RaceLogStartOfTrackingEvent { - private static final long serialVersionUID = -4134608549471817247L; - - public RaceLogStartOfTrackingEventImpl(TimePoint createdAt, AbstractLogEventAuthor author, - TimePoint startOfTracking, Serializable pId, List pInvolvedBoats, int pPassId) { - super(createdAt, author, startOfTracking, pId, pInvolvedBoats, pPassId); - // TODO Auto-generated constructor stub - } - - @Override - public void accept(RaceLogEventVisitor visitor) { - visitor.visit(this); - } -} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogSuppressedMarkPassingsEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/SuppressedMarkPassingsEventImpl.java similarity index 74% rename from java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogSuppressedMarkPassingsEventImpl.java rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/SuppressedMarkPassingsEventImpl.java index 87c45b3e975..84d99673220 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/RaceLogSuppressedMarkPassingsEventImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/SuppressedMarkPassingsEventImpl.java @@ -5,17 +5,17 @@ import java.util.List; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.base.Competitor; import com.sap.sse.common.TimePoint; -public class RaceLogSuppressedMarkPassingsEventImpl extends RaceLogEventImpl implements RaceLogSuppressedMarkPassingsEvent { +public class SuppressedMarkPassingsEventImpl extends RaceLogEventImpl implements SuppressedMarkPassingsEvent { private static final long serialVersionUID = 3665678555023150888L; private final Integer indexOfFirstSuppressedWaypoint; - public RaceLogSuppressedMarkPassingsEventImpl(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable pId, + public SuppressedMarkPassingsEventImpl(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable pId, List pInvolvedBoats, int pPassId, Integer indexOfFirstSuppressedWaypoint) { super(createdAt, author, logicalTimePoint, pId, pInvolvedBoats, pPassId); this.indexOfFirstSuppressedWaypoint = indexOfFirstSuppressedWaypoint; diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/WeakRaceLogChangedVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/WeakRaceLogChangedVisitor.java index a056688314a..cb206fea1fa 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/WeakRaceLogChangedVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/WeakRaceLogChangedVisitor.java @@ -14,10 +14,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; /** * A listener that unregisters itself from the race log's listeners if its notification target is no longer strongly - * referenced. Note that the visitor is not automatically registered by the constructor although the - * {@link RaceLog} object is passed in. - * {@link RaceLog#addListener(com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor) registration} of this visitor - * as a listener on the {@link RaceLog} has to happen explicitly by the client. + * referenced. * * @author Axel Uhl (d043530) * @@ -33,7 +30,7 @@ public class WeakRaceLogChangedVisitor extends AbstractRaceLogChangedVisitor { while (true) { try { Reference ref = queue.remove(); - WeakRaceLogChangedVisitor visitor = referenceToVisitor.remove(ref); + WeakRaceLogChangedVisitor visitor = referenceToVisitor.get(ref); visitor.removeListener(); } catch (InterruptedException e) { logger.log(Level.SEVERE, "Error trying to clean weak reference", e); @@ -48,12 +45,6 @@ public class WeakRaceLogChangedVisitor extends AbstractRaceLogChangedVisitor { private final WeakReference listenerRef; private final RaceLog removeFromThisRaceLogWhenListenerNoLongerStronglyReferenced; - /** - * Remembers from which {@link RaceLog} to {@link RaceLog#removeListener(Object) remove} this visitor as a listener - * when the listener is no longer strongly referenced. This constructor does not register this - * visitor as a listener on the {@link RaceLog}. This has to happen explicitly by the caller after this constructor - * has returned. - */ public WeakRaceLogChangedVisitor(RaceLog removeFromThisRaceLogWhenListenerNoLongerStronglyReferenced, RaceLogChangedListener listener) { this.removeFromThisRaceLogWhenListenerNoLongerStronglyReferenced = removeFromThisRaceLogWhenListenerNoLongerStronglyReferenced; listenerRef = new WeakReference(listener, queue); 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 bfef08ff52a..e1bacfe4d6e 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 @@ -19,7 +19,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.IsInFinishingPhase import com.sap.sailing.domain.abstractlog.race.analyzing.impl.IsIndividualRecallDisplayedAnalyzer; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder; -import com.sap.sailing.domain.abstractlog.race.impl.WeakRaceLogChangedVisitor; +import com.sap.sailing.domain.abstractlog.race.impl.RaceLogChangedVisitor; 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.ReadonlyRaceState; @@ -79,10 +79,12 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i if (configuration == null) { throw new IllegalArgumentException("configuration must not be null"); } + this.raceLog = raceLog; this.author = author; this.factory = factory; this.configuration = configuration; + this.changedListeners = createChangedListenerContainer(); this.isRecallDisplayedAnalyzer = new IsIndividualRecallDisplayedAnalyzer(raceLog); this.recallDisplayedFinder = new IndividualRecallDisplayedFinder(raceLog); @@ -90,8 +92,10 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i this.finishingTimeFinder = new FinishingTimeFinder(raceLog); this.finishedTimeFinder = new FinishedTimeFinder(raceLog); this.startTimeFinder = new StartTimeFinder(raceLogResolver, raceLog); - this.raceLogListener = new WeakRaceLogChangedVisitor(this.raceLog, this); - this.raceLog.addListener(this.raceLogListener); + + this.raceLogListener = new RaceLogChangedVisitor(this); + this.raceLog.addListener(raceLogListener); + this.cachedIsIndividualRecallDisplayed = false; } @@ -224,6 +228,7 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i protected void update() { boolean isRecallDisplayed = isRecallDisplayedAnalyzer.analyze(); + if (cachedIsIndividualRecallDisplayed != isRecallDisplayed) { cachedIsIndividualRecallDisplayed = isRecallDisplayed; if (cachedIsIndividualRecallDisplayed) { @@ -233,7 +238,8 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i changedListeners.onIndividualRecallRemoved(this); unscheduleStateEvent(RaceStateEvents.INDIVIDUAL_RECALL_TIMEOUT); } - } + } + // always call listeners for changed flag, as this does not only affect recall, but also // changes start procedure, for which some text elements need to be updated // ({@link BaseRaceInfoFragmen#renderFlagChangesCountdown} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/EventBase.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/EventBase.java index f642b939199..36830a08816 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/EventBase.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/EventBase.java @@ -81,14 +81,6 @@ public interface EventBase extends Named, WithDescription, Renamable, WithID, Wi void setOfficialWebsiteURL(URL officialWebsiteURL); - /** - * @return the URL of an external web site containing sailor related information like protests, official results, etc. - * or null if such a site does not exist or its URL is not known. - */ - URL getSailorsInfoWebsiteURL(); - - void setSailorsInfoWebsiteURL(URL sailorsInfoWebsiteURL); - Iterable getLeaderboardGroups(); /** diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/Leg.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/Leg.java index 2aafa18c39f..0574630703d 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/Leg.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/Leg.java @@ -2,23 +2,8 @@ package com.sap.sailing.domain.base; import java.io.Serializable; -/** - * When two legs are compared, their natural order is by the index of their {@link #getFrom() start waypoint} in the - * {@link Course} to which they belong. A leg closer to the beginning of the course ranks "less" than one that is closer - * to the end of the course. - * - * @author Axel Uhl (D043530) - * - */ -public interface Leg extends Serializable, Comparable { +public interface Leg extends Serializable { Waypoint getFrom(); Waypoint getTo(); - - /** - * The index of this leg's {@link #getFrom() start waypoint} in the sequence of the - * {@link Course}'s {@link Course#getWaypoints waypoints}. The first waypoint in - * the course has index 0. - */ - int getZeroBasedIndexOfStartWaypoint(); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CourseDataImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CourseDataImpl.java index e07dbbabf31..6d956701058 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CourseDataImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CourseDataImpl.java @@ -23,6 +23,7 @@ public class CourseDataImpl extends NamedImpl implements CourseBase { @Override public List getLegs() { + // TODO Auto-generated method stub return null; } @@ -71,6 +72,7 @@ public class CourseDataImpl extends NamedImpl implements CourseBase { @Override public Leg getFirstLeg() { + // TODO Auto-generated method stub return null; } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/EventBaseImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/EventBaseImpl.java index 566fce6e2c9..2ab810449d4 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/EventBaseImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/EventBaseImpl.java @@ -36,7 +36,6 @@ public abstract class EventBaseImpl implements EventBase { private TimePoint startDate; private TimePoint endDate; private URL officialWebsiteURL; - private URL sailorsInfoWebsiteURL; private ConcurrentLinkedQueue images; private ConcurrentLinkedQueue videos; @@ -183,16 +182,6 @@ public abstract class EventBaseImpl implements EventBase { this.officialWebsiteURL = officialWebsiteURL; } - @Override - public URL getSailorsInfoWebsiteURL() { - return sailorsInfoWebsiteURL; - } - - @Override - public void setSailorsInfoWebsiteURL(URL sailorsInfoWebsiteURL) { - this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL; - } - @Override public Iterable getImages() { return Collections.unmodifiableCollection(images); diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/ranking/TestFarthestAheadWithSkippedMarkPassing.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/ranking/TestFarthestAheadWithSkippedMarkPassing.java deleted file mode 100755 index 66c194416e2..00000000000 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/ranking/TestFarthestAheadWithSkippedMarkPassing.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.sap.sailing.domain.ranking; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; -import static org.mockito.Mockito.mock; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.function.Function; - -import org.junit.Test; - -import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; -import com.sap.sailing.domain.base.Competitor; -import com.sap.sailing.domain.base.ControlPoint; -import com.sap.sailing.domain.base.Course; -import com.sap.sailing.domain.base.DomainFactory; -import com.sap.sailing.domain.base.Mark; -import com.sap.sailing.domain.base.RaceDefinition; -import com.sap.sailing.domain.base.Regatta; -import com.sap.sailing.domain.base.Sideline; -import com.sap.sailing.domain.base.Waypoint; -import com.sap.sailing.domain.base.impl.BoatClassImpl; -import com.sap.sailing.domain.base.impl.ControlPointWithTwoMarksImpl; -import com.sap.sailing.domain.base.impl.CourseImpl; -import com.sap.sailing.domain.base.impl.MarkImpl; -import com.sap.sailing.domain.base.impl.RaceDefinitionImpl; -import com.sap.sailing.domain.base.impl.RegattaImpl; -import com.sap.sailing.domain.base.impl.WaypointImpl; -import com.sap.sailing.domain.common.RankingMetrics; -import com.sap.sailing.domain.common.ScoringSchemeType; -import com.sap.sailing.domain.common.WindSourceType; -import com.sap.sailing.domain.common.impl.DegreeBearingImpl; -import com.sap.sailing.domain.common.impl.DegreePosition; -import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl; -import com.sap.sailing.domain.common.impl.WindImpl; -import com.sap.sailing.domain.common.impl.WindSourceImpl; -import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl; -import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl; -import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore; -import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore; -import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo; -import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore; -import com.sap.sailing.domain.test.TrackBasedTest; -import com.sap.sailing.domain.tracking.DynamicTrackedRace; -import com.sap.sailing.domain.tracking.MarkPassing; -import com.sap.sailing.domain.tracking.TrackedRegatta; -import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl; -import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl; -import com.sap.sailing.domain.tracking.impl.EmptyWindStore; -import com.sap.sailing.domain.tracking.impl.MarkPassingImpl; -import com.sap.sse.common.Duration; -import com.sap.sse.common.TimePoint; -import com.sap.sse.common.impl.MillisecondsTimePoint; - -/** - * A test for the case described in bug 2976: when a competitor has skipped a mark passing but then got one for a - * later waypoint, that competitor may still be the one "farthest ahead." Still, we seem to have observed a case where - * under these circumstances the competitor was not considered "farthest ahead" and instead another with a contiguous - * mark passing list was preferred.

- * - * This test case establishes such a situation: two competitors, one with contiguous mark passings for the first two - * waypoints but not having sailed as far as the other in the second leg; the other competitor skipped the first mark - * passing, has one for the second waypoint and leads by windward distance in the second leg.

- * - * Since the problem occurred with the {@link OneDesignRankingMetric}, we'll use that one for the set-up here. - * - * @author Axel Uhl (D043530) - * - */ -public class TestFarthestAheadWithSkippedMarkPassing { - private RankingMetric rankingMetric; - private DynamicTrackedRace trackedRace; - private Competitor c1, c2; - private Waypoint start; - private Waypoint windward; - private Waypoint finish; - - private void setUp(TimeOnTimeFactorMapping timeOnTimeFactors, Function timeOnDistanceFactors) { - c1 = TrackBasedTest.createCompetitor("SlowBoat"); - c2 = TrackBasedTest.createCompetitor("FastBoat"); - trackedRace = createTrackedRace(Arrays.asList(c1, c2)); - rankingMetric = trackedRace.getRankingMetric(); - assertEquals(120, trackedRace.getCourseLength().getNauticalMiles(), 0.02); - assertSame(RankingMetrics.ONE_DESIGN, trackedRace.getTrackedRegatta().getRegatta().getRankingMetricType()); - } - - private DynamicTrackedRace createTrackedRace(Iterable competitors) { - final TimePoint timePointForFixes = MillisecondsTimePoint.now(); - BoatClassImpl boatClass = new BoatClassImpl("Some Handicap Boat Class", /* typicallyStartsUpwind */ true); - Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, - RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null, - DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", /* courseArea */ null, OneDesignRankingMetric::new); - TrackedRegatta trackedRegatta = new DynamicTrackedRegattaImpl(regatta); - List waypoints = new ArrayList(); - // create a two-lap upwind/downwind course: - MarkImpl left = new MarkImpl("Left lee gate buoy"); - MarkImpl right = new MarkImpl("Right lee gate buoy"); - ControlPoint leeGate = new ControlPointWithTwoMarksImpl(left, right, "Lee Gate"); - Mark windwardMark = new MarkImpl("Windward mark"); - start = new WaypointImpl(leeGate); - waypoints.add(start); - windward = new WaypointImpl(windwardMark); - waypoints.add(windward); - finish = new WaypointImpl(leeGate); - waypoints.add(finish); - Course course = new CourseImpl("Test Course", waypoints); - RaceDefinition race = new RaceDefinitionImpl("Test Race", course, boatClass, competitors); - DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections. emptyList(), EmptyWindStore.INSTANCE, - EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 0, - /* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000, - /* delay for wind estimation cache invalidation */ 0, /*useMarkPassingCalculator*/ false, - tr->new OneDesignRankingMetric(tr), mock(RaceLogResolver.class)); - // in this simplified artificial course, the top mark is exactly north of the right leeward gate - DegreePosition topPosition = new DegreePosition(1, 0); - trackedRace.getOrCreateTrack(left).addGPSFix(new GPSFixImpl(new DegreePosition(0, -0.000001), timePointForFixes)); - trackedRace.getOrCreateTrack(right).addGPSFix(new GPSFixImpl(new DegreePosition(0, 0.000001), timePointForFixes)); - trackedRace.getOrCreateTrack(windwardMark).addGPSFix(new GPSFixImpl(topPosition, timePointForFixes)); - trackedRace.recordWind(new WindImpl(topPosition, timePointForFixes, new KnotSpeedWithBearingImpl( - /* speedInKnots */14.7, new DegreeBearingImpl(180))), new WindSourceImpl(WindSourceType.WEB)); - return trackedRace; - } - - - /** - * A competitor having only the start mark passing shall be ranked farthest ahead if the only other competitor - * has no start mark passing. - */ - @Test - public void testWithOneMarkPassingOnly() { - setUp(c -> c==c1 ? 2.0 : 1.0, c -> 0.0); - final TimePoint startOfRace = MillisecondsTimePoint.now(); - final TimePoint middleOfFirstLeg = startOfRace.plus(Duration.ONE_HOUR.times(3)); - trackedRace.updateMarkPassings( - c1, - Arrays. asList(new MarkPassingImpl(startOfRace, start, c1))); - trackedRace.getTrack(c1).add( - new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(45)))); - trackedRace.getTrack(c2).add( - new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(315)))); - trackedRace.getTrack(c1).add( - new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(45)))); - trackedRace.getTrack(c2).add( - new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(315)))); - // Both boats have climbed half of the first upwind beat; c1 is rated the faster boat (2.0), c2 has time-on-time factor 1.0. - // Therefore, c2 is expected to lead after applying the corrections. - final RankingInfo rankingInfo = rankingMetric.getRankingInfo(middleOfFirstLeg); - final Competitor farthestAhead = rankingInfo.getCompetitorFarthestAhead(); - assertSame(c1, farthestAhead); - Comparator comparator = rankingMetric.getRaceRankingComparator(middleOfFirstLeg); - assertEquals(-1, comparator.compare(c1, c2)); // c1 is "less" than c2; better competitors rank less - } - - /** - * C2 skipped the start mark passing but got a valid passing for the next waypoint. In the second leg, C2 leads - * by windward distance and should therefore be listed as the competitor farthest ahead by the ranking metric. - */ - @Test - public void testWithTwoMarkPassingsForC1AndSkippedStartForC2() { - setUp(c -> c==c1 ? 2.0 : 1.0, c -> 0.0); - final TimePoint startOfRace = MillisecondsTimePoint.now(); - final TimePoint endOfFirstLeg = startOfRace.plus(Duration.ONE_HOUR.times(3)); - final TimePoint middleOfSecondLeg = endOfFirstLeg.plus(Duration.ONE_MINUTE.times(10)); - trackedRace.updateMarkPassings( - c1, - Arrays. asList(new MarkPassingImpl(startOfRace, start, c1), new MarkPassingImpl(endOfFirstLeg, windward, c1))); - trackedRace.updateMarkPassings( - c2, - Arrays. asList(/* skipping start waypoint */ new MarkPassingImpl(endOfFirstLeg, windward, c2))); - // they both start at the start line - trackedRace.getTrack(c1).add( - new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(45)))); - trackedRace.getTrack(c2).add( - new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(315)))); - // both round the windward mark at the same time - trackedRace.getTrack(c1).add( - new GPSFixMovingImpl(new DegreePosition(1.0, 0), endOfFirstLeg, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(45)))); - trackedRace.getTrack(c2).add( - new GPSFixMovingImpl(new DegreePosition(1.0, 0), endOfFirstLeg, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(315)))); - // c2 is further down the wind already at the middle of the second leg: - trackedRace.getTrack(c1).add( - new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfSecondLeg, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(180)))); - trackedRace.getTrack(c2).add( - new GPSFixMovingImpl(new DegreePosition(0.2, 0), middleOfSecondLeg, new KnotSpeedWithBearingImpl(12, - new DegreeBearingImpl(180)))); - // Assert that c2 is the boat farthest ahead - final RankingInfo rankingInfo = rankingMetric.getRankingInfo(middleOfSecondLeg); - assertSame(c2, rankingInfo.getCompetitorFarthestAhead()); - Comparator comparator = rankingMetric.getRaceRankingComparator(middleOfSecondLeg); - assertEquals(1, comparator.compare(c1, c2)); // c1 is "less" than c2; better competitors rank less - } -} diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DirectGapCalculationVersusOneDesignRankingMetricTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DirectGapCalculationVersusOneDesignRankingMetricTest.java index 1dce9263770..c3e6b4adfab 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DirectGapCalculationVersusOneDesignRankingMetricTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DirectGapCalculationVersusOneDesignRankingMetricTest.java @@ -60,7 +60,7 @@ public class DirectGapCalculationVersusOneDesignRankingMetricTest extends Abstra ReceiverType.MARKPOSITIONS, ReceiverType.RACECOURSE, ReceiverType.RAWPOSITIONS }); getTrackedRace().recordWind( new WindImpl(/* position */null, new MillisecondsTimePoint(dateFormat.parse("06/21/2014-13:03:35")), - new KnotSpeedWithBearingImpl(18, new DegreeBearingImpl(90))), + new KnotSpeedWithBearingImpl(18, new DegreeBearingImpl(296))), new WindSourceImpl(WindSourceType.WEB)); } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java index 0a44d6c0851..943e938d1d7 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java @@ -477,6 +477,11 @@ public class MockedTrackedRace implements DynamicTrackedRace { return null; } + @Override + public Iterable getTrackedRaces(BoatClass boatClass) { + return null; + } + @Override public void addTrackedRace(TrackedRace trackedRace) { } @@ -531,10 +536,6 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public void unlockTrackedRacesAfterWrite() { } - - @Override - public void removeRaceListener(RaceListener listener) { - } }; } diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/Simulator.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/Simulator.java index 6abf9b6074c..0d5bfda749a 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/Simulator.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/Simulator.java @@ -18,8 +18,6 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl; import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.MarkPassing; -import com.sap.sailing.domain.tracking.RaceListener; -import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.WindStore; import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.impl.EmptyWindStore; @@ -32,7 +30,6 @@ public class Simulator { private DynamicTrackedRace trackedRace; private final WindStore windStore; - private boolean stopped; private long advanceInMillis = -1; private Timer timer = new Timer("Timer for TracTrac Simulator"); @@ -49,20 +46,8 @@ public class Simulator { return EmptyWindStore.INSTANCE; } - public synchronized void setTrackedRace(final DynamicTrackedRace trackedRace) { + public synchronized void setTrackedRace(DynamicTrackedRace trackedRace) { this.trackedRace = trackedRace; - trackedRace.getTrackedRegatta().addRaceListener(new RaceListener() { - @Override - public void raceAdded(TrackedRace trackedRace) { - } - - @Override - public void raceRemoved(TrackedRace trackedRace) { - if (trackedRace == Simulator.this.trackedRace) { - stop(); // stop simulator when tracked race is removed from its regatta - } - } - }); startWindPlayer(); } @@ -91,15 +76,11 @@ public class Simulator { windTrack.lockForRead(); try { for (Wind wind : windTrack.getRawFixes()) { - if (stopped) { - break; - } trackedRace.recordWind(delayWind(wind), windSourceAndTrack.getKey()); } } finally { windTrack.unlockAfterRead(); } - logger.info("Wind Track Simulator for race "+trackedRace.getRace().getName()+" finished. stopped="+stopped); } }.start(); } @@ -116,11 +97,15 @@ public class Simulator { */ private synchronized long getAdvanceInMillis() { while (!isAdvanceInMillisSet()) { - try { - wait(2000); // wait for two seconds, then re-evaluate whether there is a start time - } catch (InterruptedException e) { - logger.throwing(Simulator.class.getName(), "getAdvanceInMillis", e); - // ignore; try again + if (trackedRace.getStartOfRace() != null) { + setAdvanceInMillis(System.currentTimeMillis() - trackedRace.getStartOfRace().asMillis()); + } else { + try { + wait(2000); // wait for two seconds, then re-evaluate whether there is a start time + } catch (InterruptedException e) { + logger.throwing(Simulator.class.getName(), "getAdvanceInMillis", e); + // ignore; try again + } } } return advanceInMillis; @@ -260,10 +245,4 @@ public class Simulator { }, transformedTimepoint.asDate()); } } - - public void stop() { - logger.info("Stopping simulator for race "+trackedRace.getRace().getName()); - timer.cancel(); - stopped = true; - } } diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceTrackerImpl.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceTrackerImpl.java index 48b19b05252..74ec0c4d8ad 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceTrackerImpl.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceTrackerImpl.java @@ -215,8 +215,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements private final TrackedRegattaRegistry trackedRegattaRegistry; - private final Simulator simulator; - /** * Creates a race tracked for the specified URL/URIs and starts receiving all available existing and future push * data from there. Receiving continues until {@link #stop(boolean)} is called. @@ -248,6 +246,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements * available but loses track of the wind, e.g., during server restarts. * @param trackedRegattaRegistry * used to create the {@link TrackedRegatta} for the domain event + * @param raceLogResolver TODO */ protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis, @@ -279,6 +278,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements * tracker is already known up-front, particularly if it has a specific configuration to use. Other constructors * may create a default {@link Regatta} with only a single default {@link Series} and {@link Fleet} which may not * always be what you want. + * @param raceLogResolver TODO */ protected TracTracRaceTrackerImpl(Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, @@ -303,6 +303,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements * first mark passing for the first waypoint will be set to "now." It will delay the forwarding of all * events received such that they seem to be sent in "real-time." So, more or less the time points * attached to the events sent to the receivers will again approximate the wall time. + * @param raceLogResolver TODO */ private TracTracRaceTrackerImpl(IRace tractracRace, final Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI, URI tracTracUpdateURI, TimePoint startOfTracking, @@ -321,6 +322,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements this.gpsFixStore = gpsFixStore; this.domainFactory = domainFactory; this.lastProgressPerID = new HashMap, Util.Pair>(); + final Simulator simulator; if (simulateWithStartTimeNow) { simulator = new Simulator(windStore); // don't write the transformed wind fixes into the DB again... see also bug 1974 @@ -526,9 +528,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.FINISHED, /* will be ignored */1.0); updateStatusOfTrackedRaces(); } - if (stopReceiversPreemtively && simulator != null) { - simulator.stop(); - } } } 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 ed3c8c33149..995c0e715a7 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 @@ -158,8 +158,6 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem 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); } else { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java index b68ea6ac7ff..636172c525b 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/CourseImpl.java @@ -209,16 +209,12 @@ public class CourseImpl extends NamedImpl implements Course { @Override public Leg getFirstLeg() { - Leg result = null; - if (!legs.isEmpty()) { - try { - result = legs.get(0); - } catch (IndexOutOfBoundsException e) { - // The legs collection could have turned empty since the check; we don't want to have to lock here... - // Yes, it's a bit clumsy, but this way it's still atomic without requiring a lock which is even more expensives - } + try { + return legs.get(0); + } catch (IndexOutOfBoundsException e) { + // yes, it's a bit clumsy, but this way it's still atomic without requiring a lock which is even more expensive + return null; } - return result; } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/LegImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/LegImpl.java index 4be5581406b..d7bc8560729 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/LegImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/LegImpl.java @@ -28,14 +28,4 @@ public class LegImpl implements Leg { public String toString() { return getFrom() + " -> " + getTo(); } - - @Override - public int getZeroBasedIndexOfStartWaypoint() { - return indexOfStartWaypoint; - } - - @Override - public int compareTo(Leg o) { - return getZeroBasedIndexOfStartWaypoint() - o.getZeroBasedIndexOfStartWaypoint(); - } } \ No newline at end of file diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java index 43a03747b95..aee01674478 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java @@ -2,8 +2,7 @@ package com.sap.sailing.domain.base.impl; import java.io.Serializable; -import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseAreaChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; @@ -18,11 +17,10 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPathfinderEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartProcedureChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogCloseOpenEndedDeviceMappingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDefineMarkEvent; @@ -158,12 +156,12 @@ public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Seriali } @Override - public void visit(RaceLogFixedMarkPassingEvent event) { + public void visit(FixedMarkPassingEvent event) { notifyOnAdd(event); } @Override - public void visit(RaceLogSuppressedMarkPassingsEvent event) { + public void visit(SuppressedMarkPassingsEvent event) { notifyOnAdd(event); } @@ -176,14 +174,4 @@ public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Seriali public void visit(RaceLogDependentStartTimeEvent event) { notifyOnAdd(event); } - - @Override - public void visit(RaceLogStartOfTrackingEvent event) { - notifyOnAdd(event); - } - - @Override - public void visit(RaceLogEndOfTrackingEvent event) { - notifyOnAdd(event); - } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java index e5f14034d65..4e62ef7df1c 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java @@ -54,11 +54,11 @@ public interface Leaderboard extends LeaderboardBase { */ public interface Entry { int getTrackedRank(); - Double getNetPoints(); - Double getNetPointsUncorrected(); - Double getTotalPoints(); + Double getNetPoints() throws NoWindException; + Double getNetPointsUncorrected() throws NoWindException; + Double getTotalPoints() throws NoWindException; MaxPointsReason getMaxPointsReason(); - boolean isDiscarded(); + boolean isDiscarded() throws NoWindException; /** * Tells if the net points have been corrected by a {@link ScoreCorrection} */ diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 307d43dd716..8f383281d98 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -219,7 +219,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race return fleet; } @Override - public Double getNetPointsUncorrected() { + public Double getNetPointsUncorrected() throws NoWindException { try { return netPointsUncorrectedProvider.call(); } catch (Exception e) { @@ -1140,10 +1140,10 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race } else { suppressedCompetitors.remove(competitor); } + getScoreCorrection().notifyListenersAboutIsSuppressedChange(competitor, suppressed); } finally { LockUtil.unlockAfterWrite(suppressedCompetitorsLock); } - getScoreCorrection().notifyListenersAboutIsSuppressedChange(competitor, suppressed); } @Override @@ -1280,12 +1280,21 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race final Set discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this, getRaceColumns(), timePoint); for (final RaceColumn raceColumn : this.getRaceColumns()) { RunnableFuture future = new FutureTask(() -> { - Entry entry = AbstractSimpleLeaderboardImpl.this.getEntry(competitor, raceColumn, timePoint, discardedRaceColumns); - return getLeaderboardEntryDTO(entry, raceColumn, competitor, timePoint, - namesOfRaceColumnsForWhichToLoadLegDetails != null - && namesOfRaceColumnsForWhichToLoadLegDetails.contains(raceColumn - .getName()), waitForLatestAnalyses, legRanksCache, baseDomainFactory, - fillNetPointsUncorrected, cache); + try { + Entry entry = AbstractSimpleLeaderboardImpl.this.getEntry(competitor, raceColumn, timePoint, discardedRaceColumns); + return getLeaderboardEntryDTO(entry, raceColumn, competitor, timePoint, + namesOfRaceColumnsForWhichToLoadLegDetails != null + && namesOfRaceColumnsForWhichToLoadLegDetails.contains(raceColumn + .getName()), waitForLatestAnalyses, legRanksCache, baseDomainFactory, + fillNetPointsUncorrected, cache); + } catch (NoWindException e) { + logger.info("Exception trying to compute leaderboard entry for competitor " + + competitor.getName() + " in race column " + raceColumn.getName() + ": " + + e.getMessage()); + logger.throwing(AbstractSimpleLeaderboardImpl.class.getName(), + "computeLeaderboardByName.future.call()", e); + throw new NoWindError(e); + } }); executor.execute(future); futuresForColumnName.put(raceColumn.getName(), future); @@ -1356,7 +1365,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race private LeaderboardEntryDTO getLeaderboardEntryDTO(Entry entry, RaceColumn raceColumn, Competitor competitor, TimePoint timePoint, boolean addLegDetails, boolean waitForLatestAnalyses, Map> legRanksCache, DomainFactory baseDomainFactory, - boolean fillNetPointsUncorrected, WindLegTypeAndLegBearingCache cache) { + boolean fillNetPointsUncorrected, WindLegTypeAndLegBearingCache cache) throws NoWindException { LeaderboardEntryDTO entryDTO = new LeaderboardEntryDTO(); TrackedRace trackedRace = raceColumn.getTrackedRace(competitor); entryDTO.race = trackedRace == null ? null : trackedRace.getRaceIdentifier(); @@ -1532,7 +1541,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race */ private RaceDetails getRaceDetails(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, Map> legRanksCache, - RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) throws InterruptedException, ExecutionException { + RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) throws NoWindException, InterruptedException, ExecutionException { final RaceDetails raceDetails; if (trackedRace.getEndOfTracking() != null && trackedRace.getEndOfTracking().compareTo(timePoint) < 0) { raceDetails = getRaceDetailsForEndOfTrackingFromCacheOrCalculateAndCache(trackedRace, competitor, legRanksCache, rankingInfo, cache); @@ -1544,7 +1553,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race private RaceDetails getRaceDetailsForEndOfTrackingFromCacheOrCalculateAndCache(final TrackedRace trackedRace, final Competitor competitor, final Map> legRanksCache, - RankingInfo rankingInfo, final WindLegTypeAndLegBearingCache cache) throws InterruptedException, ExecutionException { + RankingInfo rankingInfo, final WindLegTypeAndLegBearingCache cache) throws NoWindException, InterruptedException, ExecutionException { final com.sap.sse.common.Util.Pair key = new com.sap.sse.common.Util.Pair(trackedRace, competitor); RunnableFuture raceDetails; synchronized (raceDetailsAtEndOfTrackingCache) { @@ -1576,7 +1585,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race private RaceDetails calculateRaceDetails(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, Map> legRanksCache, - WindLegTypeAndLegBearingCache cache, final RankingInfo rankingInfo) { + WindLegTypeAndLegBearingCache cache, final RankingInfo rankingInfo) throws NoWindException { final List legDetails = new ArrayList(); final Course course = trackedRace.getRace().getCourse(); course.lockForRead(); // hold back any course re-configurations while looping over the legs @@ -1624,7 +1633,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race private LegEntryDTO createLegEntry(TrackedLegOfCompetitor trackedLeg, TimePoint timePoint, boolean waitForLatestAnalyses, Map> legRanksCache, - RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) { + RankingInfo rankingInfo, WindLegTypeAndLegBearingCache cache) throws NoWindException { LegEntryDTO result; final Duration time = trackedLeg.getTime(timePoint); if (trackedLeg == null || time == null) { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java index b58f433eb1d..0ca5b8372ca 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ScoreCorrectionImpl.java @@ -2,11 +2,12 @@ package com.sap.sailing.domain.leaderboard.impl; import java.io.IOException; import java.io.ObjectInputStream; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.NavigableSet; import java.util.Set; import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -39,12 +40,12 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection { /** * If no max point reason is provided for a competitor/race, {@link MaxPointsReason#NONE} should be the default. */ - private final ConcurrentHashMap, MaxPointsReason> maxPointsReasons; + private final Map, MaxPointsReason> maxPointsReasons; /** * If no score correction is provided here, the uncorrected points are the default. */ - private final ConcurrentHashMap, Double> correctedScores; + private final Map, Double> correctedScores; /** * If null, despite a non-null {@link #timePointOfLastCorrectionsValidity} value the @@ -66,8 +67,8 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection { public ScoreCorrectionImpl(Leaderboard leaderboard) { this.leaderboard = leaderboard; - this.maxPointsReasons = new ConcurrentHashMap<>(); - this.correctedScores = new ConcurrentHashMap<>(); + this.maxPointsReasons = new HashMap, MaxPointsReason>(); + this.correctedScores = new HashMap, Double>(); this.scoreCorrectionListeners = new HashSet(); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java index 06f43a3bdf3..6578180593e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java @@ -8,7 +8,6 @@ import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.SpeedWithBearing; import com.sap.sailing.domain.common.confidence.Weigher; -import com.sap.sailing.domain.common.impl.KnotSpeedImpl; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sse.common.TimePoint; @@ -28,7 +27,6 @@ import com.sap.sse.common.Util; */ public interface GPSFixTrack extends Track { static final long DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_SPEED = 10000; // makes for a 5s half-side interval - static final Speed DEFAULT_MAX_SPEED_FOR_SMOOTHING = new KnotSpeedImpl(40); /** * A listener is notified whenever a new fix is added to this track diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java index f7497929a75..d856219aab4 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java @@ -195,7 +195,7 @@ public interface TrackedLegOfCompetitor extends Serializable { * timePoint, returns the VMG value for this time point. If the competitor has already finished the * leg, the VMG at the time when the competitor finished the leg is returned. */ - Speed getVelocityMadeGood(TimePoint timePoint, WindPositionMode windPositionMode); + Speed getVelocityMadeGood(TimePoint timePoint, WindPositionMode windPositionMode) throws NoWindException; /** * Same as {@link #getVelocityMadeGood(TimePoint, WindPositionMode)}, only that a cache for wind data and leg type and bearing @@ -212,7 +212,7 @@ public interface TrackedLegOfCompetitor extends Serializable { /** * Same as {@link #getEstimatedTimeToNextMark(TimePoint, WindPositionMode)}, only that a cache for leg type calculation is passed. */ - Duration getEstimatedTimeToNextMark(TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache); + Duration getEstimatedTimeToNextMark(TimePoint timePoint, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) throws NoWindException; /** * Returns null in case this leg's competitor hasn't started the leg yet. If in the leg at diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRegatta.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRegatta.java index c0ba2006c9b..9fa20136bed 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRegatta.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRegatta.java @@ -3,6 +3,7 @@ package com.sap.sailing.domain.tracking; import java.io.Serializable; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; +import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; @@ -54,6 +55,8 @@ public interface TrackedRegatta extends Serializable { void unlockTrackedRacesAfterWrite(); + Iterable getTrackedRaces(BoatClass boatClass); + /** * Creates a {@link TrackedRace} based on the parameter specified and {@link #addTrackedRace(TrackedRace) adds} it * to this tracked regatta. Afterwards, calling {@link #getTrackedRace(RaceDefinition) getTrackedRace(raceDefinition)} @@ -90,8 +93,6 @@ public interface TrackedRegatta extends Serializable { */ void addRaceListener(RaceListener listener); - void removeRaceListener(RaceListener listener); - int getNetPoints(Competitor competitor, TimePoint timePoint) throws NoWindException; void removeTrackedRace(RaceDefinition raceDefinition); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/AbstractRaceRankComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/AbstractRaceRankComparator.java index 4a0aebe880d..2863a33c5c1 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/AbstractRaceRankComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/AbstractRaceRankComparator.java @@ -2,14 +2,11 @@ package com.sap.sailing.domain.tracking.impl; import java.util.Collections; import java.util.Comparator; -import java.util.List; import java.util.NavigableSet; import java.util.SortedSet; -import java.util.logging.Logger; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Course; -import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; @@ -38,7 +35,6 @@ import com.sap.sse.common.TimePoint; * */ public abstract class AbstractRaceRankComparator> implements Comparator { - private static final Logger logger = Logger.getLogger(AbstractRaceRankComparator.class.getName()); private final TrackedRace trackedRace; private final TimePoint timePoint; private final DummyMarkPassingWithTimePointOnly markPassingWithTimePoint; @@ -63,7 +59,6 @@ public abstract class AbstractRaceRankComparator> implem if (o1 == o2) { result = 0; } else { - final Course course = trackedRace.getRace().getCourse(); NavigableSet o1MarkPassings = trackedRace.getMarkPassings(o1); NavigableSet o1MarkPassingsBeforeTimePoint; MarkPassing o1LastMarkPassingBeforeTimePoint = null; @@ -71,7 +66,6 @@ public abstract class AbstractRaceRankComparator> implem TrackedLegOfCompetitor o1Leg; trackedRace.lockForRead(o1MarkPassings); try { - // FIXME for the XMLExportTest.testExportingESSNice2014 the "inclusive" parameter doesn't seem to work properly; problem is caused by the MarkPassingByTimeComparator falling back to competitor ID if times are equal o1MarkPassingsBeforeTimePoint = o1MarkPassings.headSet( markPassingWithTimePoint, /* inclusive */true); o1MarkPassingsBeforeTimePointSize = o1MarkPassingsBeforeTimePoint.size(); @@ -98,43 +92,32 @@ public abstract class AbstractRaceRankComparator> implem } finally { trackedRace.unlockAfterRead(o2MarkPassings); } - final List legs = course.getLegs(); - result = o1LastMarkPassingBeforeTimePoint == null - ? o2LastMarkPassingBeforeTimePoint == null ? 0 // both haven't started yet - : 1 // only o2 has started; o1 is worse ("greater") than o2 - : o2LastMarkPassingBeforeTimePoint == null ? -1 // only o1 has started; o1 is better ("less") than o2 - /* both have started; any difference */ : course.getIndexOfWaypoint(o2LastMarkPassingBeforeTimePoint.getWaypoint()) - - /* in last waypoint passed? */ course.getIndexOfWaypoint(o1LastMarkPassingBeforeTimePoint.getWaypoint()); + result = o2MarkPassingsBeforeTimePointSize - o1MarkPassingsBeforeTimePointSize; // inverted: more legs means + // smaller rank if (result == 0 && o1MarkPassingsBeforeTimePointSize > 0) { - assert o2LastMarkPassingBeforeTimePoint != null; // Competitors are on same leg and both have already started the first leg. // TrackedLegOfCompetitor comparison also correctly uses finish times for a leg // in case we have the final leg, so both competitors finished the race. if (o1Leg == null) { // both must already have finished race; sort by race finish time: earlier time means smaller // (better) rank - assert o2Leg == null; result = o1LastMarkPassingBeforeTimePoint.getTimePoint().compareTo( o2LastMarkPassingBeforeTimePoint.getTimePoint()); } else { - assert o2Leg != null; // otherwise, o1Leg!=null && o2Leg==null, but then o1 would have a finish mark passing and o2 not - if (o1Leg.getLeg() != o2Leg.getLeg()) { - logger.finest("Warning: competitors "+o1+" and "+o2+" in different legs ("+ - o1Leg.getLeg()+" and "+o2Leg.getLeg()+", respectively) although based on their last mark passings before "+ - timePoint+" ("+o1LastMarkPassingBeforeTimePoint+" and "+o2LastMarkPassingBeforeTimePoint+", respectively) "+ - "they should be in the same leg"); - // strange: both have the same number of mark passings but are in different legs; something is - // broken, but we can only try our best: - logger.finest("Warning: competitors "+o1+" and "+o2+" in different legs ("+ - o1Leg.getLeg()+" and "+o2Leg.getLeg()+", respectively) although based on their last mark passings before "+ - timePoint+" ("+o1LastMarkPassingBeforeTimePoint+" and "+o2LastMarkPassingBeforeTimePoint+", respectively) "+ - "they should be in the same leg"); - result = legs.indexOf(o1Leg.getLeg()) - legs.indexOf(o2Leg.getLeg()); + if (o2Leg == null) { + result = 1; // o1Leg != null, so o1 has started leg already, o2 hasn't } else { - // competitors are in same leg; compare their windward distance to go - final C wwdtgO1 = getComparisonValueForSameLeg(o1); - final C wwdtgO2 = getComparisonValueForSameLeg(o2); - result = wwdtgO1==null?wwdtgO2==null?0:-1:wwdtgO2==null?1:(lessIsBetter?1:-1)*wwdtgO1.compareTo(wwdtgO2); + if (o1Leg.getLeg() != o2Leg.getLeg()) { + // strange: both have the same number of mark passings but are in different legs; something is + // broken, but we can only try our best: + result = trackedRace.getRace().getCourse().getLegs().indexOf(o1Leg.getLeg()) - + trackedRace.getRace().getCourse().getLegs().indexOf(o2Leg.getLeg()); + } else { + // competitors are in same leg; compare their windward distance to go + final C wwdtgO1 = getComparisonValueForSameLeg(o1); + final C wwdtgO2 = getComparisonValueForSameLeg(o2); + result = wwdtgO1==null?wwdtgO2==null?0:-1:wwdtgO2==null?1:(lessIsBetter?1:-1)*wwdtgO1.compareTo(wwdtgO2); + } } } } 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 9803974aff9..e64d764f230 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 @@ -4,7 +4,7 @@ import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; -import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; +import com.sap.sailing.domain.abstractlog.race.FixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogCourseDesignChangedEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; @@ -14,7 +14,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; -import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent; +import com.sap.sailing.domain.abstractlog.race.SuppressedMarkPassingsEvent; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.AbortingFlagFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.MarkPassingDataFinder; @@ -216,7 +216,7 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor { } @Override - public void visit(RaceLogFixedMarkPassingEvent event) { + public void visit(FixedMarkPassingEvent event) { if (markPassingUpdateListener != null) { markPassingUpdateListener.addFixedPassing(event.getInvolvedBoats().get(0), event.getZeroBasedIndexOfPassedWaypoint(), event.getTimePointOfFixedPassing()); @@ -224,7 +224,7 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor { } @Override - public void visit(RaceLogSuppressedMarkPassingsEvent event) { + public void visit(SuppressedMarkPassingsEvent event) { if (markPassingUpdateListener != null) { markPassingUpdateListener.addSuppressedPassing(event.getInvolvedBoats().get(0), event.getZeroBasedIndexOfFirstSuppressedWaypoint()); @@ -247,12 +247,12 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor { } } - if (revokedEvent instanceof RaceLogSuppressedMarkPassingsEvent) { + if (revokedEvent instanceof SuppressedMarkPassingsEvent) { markPassingUpdateListener.removeSuppressedPassing(revokedEvent.getInvolvedBoats().get(0)); } - if (revokedEvent instanceof RaceLogFixedMarkPassingEvent) { + if (revokedEvent instanceof FixedMarkPassingEvent) { markPassingUpdateListener.removeFixedPassing(revokedEvent.getInvolvedBoats().get(0), - ((RaceLogFixedMarkPassingEvent) revokedEvent).getZeroBasedIndexOfPassedWaypoint()); + ((FixedMarkPassingEvent) revokedEvent).getZeroBasedIndexOfPassedWaypoint()); } } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java index cb236eaa659..8cf2cc16b9f 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java @@ -33,6 +33,7 @@ import com.sap.sailing.domain.common.confidence.ConfidenceFactory; import com.sap.sailing.domain.common.confidence.HasConfidence; import com.sap.sailing.domain.common.confidence.Weigher; import com.sap.sailing.domain.common.confidence.impl.BearingWithConfidenceImpl; +import com.sap.sailing.domain.common.impl.KnotSpeedImpl; import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl; import com.sap.sailing.domain.common.impl.NauticalMileDistance; import com.sap.sailing.domain.common.tracking.GPSFix; @@ -51,6 +52,7 @@ import com.sap.sse.util.impl.ArrayListNavigableSet; public class GPSFixTrackImpl extends TrackImpl implements GPSFixTrack { private static final Logger logger = Logger.getLogger(GPSFixTrackImpl.class.getName()); private static final long serialVersionUID = -7282869695818293745L; + private static final Speed DEFAULT_MAX_SPEED_FOR_SMOOTHING = new KnotSpeedImpl(50); protected final Speed maxSpeedForSmoothing; private final ItemType trackedItem; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingByTimeComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingByTimeComparator.java index 5260036c328..28a3208b1ab 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingByTimeComparator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingByTimeComparator.java @@ -6,24 +6,35 @@ import java.util.Comparator; import com.sap.sailing.domain.tracking.MarkPassing; /** - * Compares two {@link MarkPassing} objects, using their {@link MarkPassing#getTimePoint() time point} as the only - * ordering criterion in ascending order. If two mark passings have equal time points, they are considered equal, - * regardless the competitor. Don't use this comparator for collections in which mark passings for multiple competitors - * may be managed and shall be treated as different. Use {@link MarkPassingsByTimeAndCompetitorIdComparator} instead. + * Compares two {@link MarkPassing} objects, using their {@link MarkPassing#getTimePoint() time point} as the primary + * ordering criterion in ascending order. If two mark passings have equal time points, the competitor IDs' string + * representations are compared as the secondary ordering criterion to ensure that two competitors passing a mark at the + * same time are still identified as not being equal. * * @author Axel Uhl (D043530) * */ public class MarkPassingByTimeComparator implements Comparator, Serializable { private static final long serialVersionUID = 5758820139503482888L; - public static final MarkPassingByTimeComparator INSTANCE = new MarkPassingByTimeComparator(); + public static MarkPassingByTimeComparator INSTANCE = new MarkPassingByTimeComparator(); @Override public int compare(MarkPassing o1, MarkPassing o2) { - return o1 == null ? - o2 == null ? 0 : -1 - : o2 == null ? 1 : o1.getTimePoint() == null ? - (o2.getTimePoint() == null ? 0 : -1) - : o2.getTimePoint() == null ? 1 : o1.getTimePoint().compareTo(o2.getTimePoint()); + int result = o1 == null ? o2 == null ? 0 : -1 : o2 == null ? 1 : o1.getTimePoint() == null ? (o2.getTimePoint() == null ? 0 : -1) : o2.getTimePoint() == null ? 1 : o1.getTimePoint().compareTo(o2.getTimePoint()); + if (result == 0 && o1 != null) { + assert o2 != null; + Object c1ID = o1.getCompetitor().getId(); + Object c2ID = o2.getCompetitor().getId(); + // shortcut comparison and don't use expensive toString() in case IDs are comparable by nature + if (c1ID instanceof Comparable && c1ID.getClass() == c2ID.getClass()) { + @SuppressWarnings("unchecked") + final Comparable c1OID = (Comparable) c1ID; + result = c1OID.compareTo(o2.getCompetitor().getId()); + } else { + result = o1.getCompetitor().getId().toString().compareTo(o2.getCompetitor().getId().toString()); + } + } + return result; } + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingsByTimeAndCompetitorIdComparator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingsByTimeAndCompetitorIdComparator.java deleted file mode 100644 index fb875f97b9b..00000000000 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/MarkPassingsByTimeAndCompetitorIdComparator.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.sap.sailing.domain.tracking.impl; - -import com.sap.sailing.domain.tracking.MarkPassing; - -/** - * Compares two {@link MarkPassing} objects, using their {@link MarkPassing#getTimePoint() time point} as the primary - * ordering criterion in ascending order. If two mark passings have equal time points, the competitor IDs' string - * representations are compared as the secondary ordering criterion to ensure that two competitors passing a mark at the - * same time are still identified as not being equal. - * - * @author Axel Uhl (D043530) - * - */ -public class MarkPassingsByTimeAndCompetitorIdComparator extends MarkPassingByTimeComparator { - private static final long serialVersionUID = 5977491869367296660L; - public static final MarkPassingsByTimeAndCompetitorIdComparator INSTANCE = new MarkPassingsByTimeAndCompetitorIdComparator(); - - @Override - public int compare(MarkPassing o1, MarkPassing o2) { - int result = super.compare(o1, o2); - if (result == 0 && o1 != null) { - assert o2 != null; - Object c1ID = o1.getCompetitor().getId(); - Object c2ID = o2.getCompetitor().getId(); - // shortcut comparison and don't use expensive toString() in case IDs are comparable by nature - if (c1ID instanceof Comparable && c1ID.getClass() == c2ID.getClass()) { - @SuppressWarnings("unchecked") - final Comparable c1OID = (Comparable) c1ID; - result = c1OID.compareTo(o2.getCompetitor().getId()); - } else { - result = o1.getCompetitor().getId().toString().compareTo(o2.getCompetitor().getId().toString()); - } - } - return result; - } -} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java index 47b7e3714a3..7b93db79d07 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegImpl.java @@ -344,7 +344,7 @@ public class TrackedLegImpl implements TrackedLeg { WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) { final Distance preResult = getWindwardDistance(pos1, pos2, at, windPositionMode, cache); final Distance result; - if (preResult == null || preResult.getMeters() >= 0) { + if (preResult.getMeters() >= 0) { result = preResult; } else { result = new MeterDistance(-preResult.getMeters()); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java index 8b884a4f3db..b0bdde607a6 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java @@ -228,15 +228,9 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor { * bearing, and the distance from the projection to the mark is returned. Otherwise, it is assumed that * the leg is neither an upwind nor a downwind leg, and hence the true distance to mark is returned. A * cache for wind and leg type / bearing can be passed to avoid their redundant calculation during a single - * round-trip. - *

+ * round-trip.

* * If no wind information is available, again the true geometrical distance to mark is returned. - *

- * - * If the competitor's position or the mark's position cannot be determined, null is returned. - * null is also returned if the leg's bearing cannot be determined because for at least one of its two - * waypoints no mark has a known position. */ private Distance getWindwardDistanceTo(Mark mark, TimePoint at, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) { Position estimatedPosition = getTrackedRace().getTrack(getCompetitor()).getEstimatedPosition(at, false); @@ -290,13 +284,11 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor { // as fallback in the absence of wind information, project to leg bearing projectToBearing = cache.getLegBearing(getTrackedLeg(), at); } - if (speed.getBearing() != null && projectToBearing != null) { - double cos = Math.cos(speed.getBearing().getRadians() - projectToBearing.getRadians()); - if (cos < 0) { - projectToBearing = projectToBearing.reverse(); - } - result = new KnotSpeedWithBearingImpl(Math.abs(speed.getKnots() * cos), projectToBearing); + double cos = Math.cos(speed.getBearing().getRadians() - projectToBearing.getRadians()); + if (cos < 0) { + projectToBearing = projectToBearing.reverse(); } + result = new KnotSpeedWithBearingImpl(Math.abs(speed.getKnots() * cos), projectToBearing); } return result; } @@ -346,12 +338,10 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor { } final Position endPos = getTrackedRace().getTrack(getCompetitor()).getEstimatedPosition(to, /* extrapolate */false); if (endPos != null) { - final Position startPos = getTrackedRace().getTrack(getCompetitor()).getEstimatedPosition(start.getTimePoint(), false); - if (startPos != null) { - Distance d = getTrackedLeg().getAbsoluteWindwardDistance(startPos, endPos, to, - WindPositionMode.EXACT, cache); - result = d.inTime(to.asMillis() - start.getTimePoint().asMillis()); - } + Distance d = getTrackedLeg().getAbsoluteWindwardDistance( + getTrackedRace().getTrack(getCompetitor()).getEstimatedPosition(start.getTimePoint(), false), + endPos, to, WindPositionMode.EXACT, cache); + result = d.inTime(to.asMillis() - start.getTimePoint().asMillis()); } } return result; @@ -623,7 +613,7 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor { } @Override - public Speed getVelocityMadeGood(TimePoint at, WindPositionMode windPositionMode) { + public Speed getVelocityMadeGood(TimePoint at, WindPositionMode windPositionMode) throws NoWindException { return getVelocityMadeGood(at, windPositionMode, new LeaderboardDTOCalculationReuseCache(at)); } 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 076898280e9..786c4db1a11 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 @@ -452,7 +452,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl markPassingsForWaypoint = new ConcurrentHashMap>(); for (Waypoint waypoint : race.getCourse().getWaypoints()) { markPassingsForWaypoint.put(waypoint, new ConcurrentSkipListSet( - MarkPassingsByTimeAndCompetitorIdComparator.INSTANCE)); + MarkPassingByTimeComparator.INSTANCE)); } markPassingsTimes = new ArrayList>>(); loadingFromWindStoreState = LoadingFromStoresState.NOT_STARTED; @@ -697,7 +697,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl protected NavigableSet createMarkPassingsCollectionForWaypoint(Waypoint waypoint) { final ConcurrentSkipListSet result = new ConcurrentSkipListSet( - MarkPassingsByTimeAndCompetitorIdComparator.INSTANCE); + MarkPassingByTimeComparator.INSTANCE); LockUtil.lockForRead(getSerializationLock()); try { markPassingsForWaypoint.put(waypoint, result); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRegattaImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRegattaImpl.java index 3b92f7ced2d..361c2cbfa71 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRegattaImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRegattaImpl.java @@ -5,14 +5,17 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; +import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; @@ -48,19 +51,21 @@ public class TrackedRegattaImpl implements TrackedRegatta { */ private final Map trackedRaces; - private transient ConcurrentHashMap raceListeners; + private final Map> trackedRacesByBoatClass; + private transient Set raceListeners; public TrackedRegattaImpl(Regatta regatta) { super(); trackedRacesLock = new NamedReentrantReadWriteLock("trackeRaces lock for tracked regatta "+regatta.getName(), /* fair */ false); this.regatta = regatta; this.trackedRaces = new HashMap(); - raceListeners = new ConcurrentHashMap(); + this.trackedRacesByBoatClass = new HashMap>(); + raceListeners = new HashSet(); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); - this.raceListeners = new ConcurrentHashMap(); + this.raceListeners = new HashSet(); } @Override @@ -99,22 +104,31 @@ public class TrackedRegattaImpl implements TrackedRegatta { private Object readResolve() throws ObjectStreamException { TrackedRegattaImpl result = new TrackedRegattaImpl(this.regatta); result.trackedRaces.putAll(this.trackedRaces); + result.trackedRacesByBoatClass.putAll(this.trackedRacesByBoatClass); return result; } @Override public void addTrackedRace(TrackedRace trackedRace) { final TrackedRace oldTrackedRace; - lockTrackedRacesForWrite(); + LockUtil.lockForWrite(trackedRacesLock); try { logger.info("adding tracked race for "+trackedRace.getRace()+" to tracked regatta "+getRegatta().getName()+ " with regatta hash code "+getRegatta().hashCode()); oldTrackedRace = trackedRaces.put(trackedRace.getRace(), trackedRace); + if (oldTrackedRace != trackedRace) { + Collection coll = trackedRacesByBoatClass.get(trackedRace.getRace().getBoatClass()); + if (coll == null) { + coll = new ArrayList(); + trackedRacesByBoatClass.put(trackedRace.getRace().getBoatClass(), coll); + } + coll.add(trackedRace); + } } finally { - unlockTrackedRacesAfterWrite(); + LockUtil.unlockAfterWrite(trackedRacesLock); } if (oldTrackedRace != trackedRace) { - for (RaceListener listener : raceListeners.keySet()) { + for (RaceListener listener : raceListeners) { listener.raceAdded(trackedRace); } } @@ -135,7 +149,14 @@ public class TrackedRegattaImpl implements TrackedRegatta { LockUtil.lockForWrite(trackedRacesLock); try { trackedRaces.remove(trackedRace.getRace()); - for (RaceListener listener : raceListeners.keySet()) { + Collection trbbc = trackedRacesByBoatClass.get(trackedRace.getRace().getBoatClass()); + if (trbbc != null) { + trbbc.remove(trackedRace); + if (trbbc.isEmpty()) { + trackedRacesByBoatClass.remove(trackedRace.getRace().getBoatClass()); + } + } + for (RaceListener listener : raceListeners) { listener.raceRemoved(trackedRace); } } finally { @@ -156,41 +177,29 @@ public class TrackedRegattaImpl implements TrackedRegatta { return trackedRaces.values(); } + @Override + public Iterable getTrackedRaces(BoatClass boatClass) { + return trackedRacesByBoatClass.get(boatClass); + } + @Override public TrackedRace getTrackedRace(RaceDefinition race) { boolean interrupted = false; - TrackedRace result = getExistingTrackedRace(race); - if (!interrupted && result == null) { - final Object mutex = new Object(); - final RaceListener listener = new RaceListener() { - @Override - public void raceRemoved(TrackedRace trackedRace) {} - - @Override - public void raceAdded(TrackedRace trackedRace) { - synchronized (mutex) { - mutex.notifyAll(); - } + lockTrackedRacesForRead(); + try { + TrackedRace result = trackedRaces.get(race); + while (!interrupted && result == null) { + try { + trackedRaces.wait(); + result = trackedRaces.get(race); + } catch (InterruptedException e) { + interrupted = true; } - }; - addRaceListener(listener); - try { - synchronized (mutex) { - result = getExistingTrackedRace(race); - while (!interrupted && result == null) { - try { - mutex.wait(); - result = getExistingTrackedRace(race); - } catch (InterruptedException e) { - interrupted = true; - } - } - } - } finally { - removeRaceListener(listener); } + return result; + } finally { + unlockTrackedRacesAfterRead(); } - return result; } @Override @@ -208,7 +217,7 @@ public class TrackedRegattaImpl implements TrackedRegatta { final List trackedRacesCopy = new ArrayList<>(); lockTrackedRacesForRead(); try { - raceListeners.put(listener, listener); + raceListeners.add(listener); Util.addAll(getTrackedRaces(), trackedRacesCopy); } finally { unlockTrackedRacesAfterRead(); @@ -218,16 +227,6 @@ public class TrackedRegattaImpl implements TrackedRegatta { } } - @Override - public void removeRaceListener(RaceListener listener) { - lockTrackedRacesForRead(); - try { - raceListeners.remove(listener); - } finally { - unlockTrackedRacesAfterRead(); - } - } - @Override public int getNetPoints(Competitor competitor, TimePoint timePoint) throws NoWindException { int result = 0; diff --git a/java/com.sap.sailing.feature.p2build/raceanalysis.product b/java/com.sap.sailing.feature.p2build/raceanalysis.product index b1682e26616..3680642bd97 100755 --- a/java/com.sap.sailing.feature.p2build/raceanalysis.product +++ b/java/com.sap.sailing.feature.p2build/raceanalysis.product @@ -47,8 +47,8 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java index 25b21ceb0c8..6656cb1e4d7 100755 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java @@ -11,6 +11,7 @@ import java.util.Set; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; +import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.CourseBase; import com.sap.sailing.domain.base.Leg; @@ -273,6 +274,11 @@ public class MockedTrackedRace implements DynamicTrackedRace { return null; } + @Override + public Iterable getTrackedRaces(BoatClass boatClass) { + return null; + } + @Override public void addTrackedRace(TrackedRace trackedRace) { } @@ -327,10 +333,6 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public void unlockTrackedRacesAfterWrite() { } - - @Override - public void removeRaceListener(RaceListener listener) { - } }; } diff --git a/java/com.sap.sailing.gwt.ui/.tmp/gwt-work/.gitignore b/java/com.sap.sailing.gwt.ui/.tmp/gwt-work/.gitignore deleted file mode 100644 index 3e3e47daf0f..00000000000 --- a/java/com.sap.sailing.gwt.ui/.tmp/gwt-work/.gitignore +++ /dev/null @@ -1 +0,0 @@ -com.* diff --git a/java/com.sap.sailing.gwt.ui/AdminConsole.html b/java/com.sap.sailing.gwt.ui/AdminConsole.html index 182b6efdd40..caafac0df47 100644 --- a/java/com.sap.sailing.gwt.ui/AdminConsole.html +++ b/java/com.sap.sailing.gwt.ui/AdminConsole.html @@ -30,7 +30,11 @@ + + + + diff --git a/java/com.sap.sailing.gwt.ui/AutoPlay.html b/java/com.sap.sailing.gwt.ui/AutoPlay.html index 7d001254302..5661b354a35 100644 --- a/java/com.sap.sailing.gwt.ui/AutoPlay.html +++ b/java/com.sap.sailing.gwt.ui/AutoPlay.html @@ -23,6 +23,8 @@ + + @@ -35,6 +37,10 @@ + + + + diff --git a/java/com.sap.sailing.gwt.ui/BrowserUnsupported.html b/java/com.sap.sailing.gwt.ui/BrowserUnsupported.html index 28a7d28944d..6ff7d6bcdd7 100644 --- a/java/com.sap.sailing.gwt.ui/BrowserUnsupported.html +++ b/java/com.sap.sailing.gwt.ui/BrowserUnsupported.html @@ -1,12 +1,27 @@ + + + + + + + + + + Your browser is unsupported + + + + + Your browser is unsupported. diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/css/CommonControls.css b/java/com.sap.sailing.gwt.ui/CommonControls.css similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/css/CommonControls.css rename to java/com.sap.sailing.gwt.ui/CommonControls.css diff --git a/java/com.sap.sailing.gwt.ui/DataMining.html b/java/com.sap.sailing.gwt.ui/DataMining.html index 9f93882c9d2..fbdb1ed443a 100644 --- a/java/com.sap.sailing.gwt.ui/DataMining.html +++ b/java/com.sap.sailing.gwt.ui/DataMining.html @@ -15,10 +15,16 @@ + - + + + + + + diff --git a/java/com.sap.sailing.gwt.ui/Home.html b/java/com.sap.sailing.gwt.ui/Home.html index c4d43930037..242a366c3e1 100644 --- a/java/com.sap.sailing.gwt.ui/Home.html +++ b/java/com.sap.sailing.gwt.ui/Home.html @@ -1,19 +1,49 @@ + + + + + + - - - + + + + + + + - SAP Sailing - Homepage - - - + + + + SAP Sailing - Homepage + + + + + + + + + + + + + + + + + + + + + + @@ -23,18 +53,25 @@ - - + - - - -

- Your web browser must have JavaScript enabled in order for this - application to display correctly.
- + + + + + + - + + + + + + + diff --git a/java/com.sap.sailing.gwt.ui/HomeDesktop.html b/java/com.sap.sailing.gwt.ui/HomeDesktop.html deleted file mode 100644 index fb2fefff91f..00000000000 --- a/java/com.sap.sailing.gwt.ui/HomeDesktop.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - SAP Sailing - Homepage - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/HomeMobile.html b/java/com.sap.sailing.gwt.ui/HomeMobile.html deleted file mode 100644 index fb2fefff91f..00000000000 --- a/java/com.sap.sailing.gwt.ui/HomeMobile.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - SAP Sailing - Homepage - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/Leaderboard.html b/java/com.sap.sailing.gwt.ui/Leaderboard.html index 39007c2c267..22f7ee9c596 100755 --- a/java/com.sap.sailing.gwt.ui/Leaderboard.html +++ b/java/com.sap.sailing.gwt.ui/Leaderboard.html @@ -16,11 +16,17 @@ - + + + - + + + + + - + diff --git a/java/com.sap.sailing.gwt.ui/LeaderboardEditing.html b/java/com.sap.sailing.gwt.ui/LeaderboardEditing.html index f1b2e94e8e1..ea7acd3c454 100755 --- a/java/com.sap.sailing.gwt.ui/LeaderboardEditing.html +++ b/java/com.sap.sailing.gwt.ui/LeaderboardEditing.html @@ -22,6 +22,7 @@ + diff --git a/java/com.sap.sailing.gwt.ui/PolarSheets.html b/java/com.sap.sailing.gwt.ui/PolarSheets.html index 8449145b9f7..9c494cbd4a7 100644 --- a/java/com.sap.sailing.gwt.ui/PolarSheets.html +++ b/java/com.sap.sailing.gwt.ui/PolarSheets.html @@ -12,12 +12,17 @@ + + + + + - + diff --git a/java/com.sap.sailing.gwt.ui/RaceBoard.html b/java/com.sap.sailing.gwt.ui/RaceBoard.html index 07683048eee..65262ac2b0d 100644 --- a/java/com.sap.sailing.gwt.ui/RaceBoard.html +++ b/java/com.sap.sailing.gwt.ui/RaceBoard.html @@ -18,10 +18,15 @@ + + + + + diff --git a/java/com.sap.sailing.gwt.ui/RegattaOverview.html b/java/com.sap.sailing.gwt.ui/RegattaOverview.html index b2edb59c4a0..2c7b1406e16 100644 --- a/java/com.sap.sailing.gwt.ui/RegattaOverview.html +++ b/java/com.sap.sailing.gwt.ui/RegattaOverview.html @@ -15,6 +15,7 @@ SAP Sailing Analytics Regatta Overview + - + + + + + + + + diff --git a/java/com.sap.sailing.gwt.ui/Spectator.html b/java/com.sap.sailing.gwt.ui/Spectator.html index 27d727c2b8c..9aec13d2910 100644 --- a/java/com.sap.sailing.gwt.ui/Spectator.html +++ b/java/com.sap.sailing.gwt.ui/Spectator.html @@ -29,6 +29,7 @@ + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ViewerToolbar.css b/java/com.sap.sailing.gwt.ui/ViewerToolbar.css similarity index 70% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ViewerToolbar.css rename to java/com.sap.sailing.gwt.ui/ViewerToolbar.css index d55a8630c74..3fd42f875f5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/ViewerToolbar.css +++ b/java/com.sap.sailing.gwt.ui/ViewerToolbar.css @@ -106,3 +106,42 @@ .viewerToolbar-innerElement label { cursor: pointer; } + +.viewerToolbar-standaloneElement { + background: url("images/btn-cta-orangeleft.png") repeat-x scroll center 0 transparent; + color: #FFFFFF; + cursor: pointer; + font-family: UbuntuBold,Verdana,Arial,sans-serif; + font-size: 14px; + margin: 0 0 0 0; + padding: 2px 7px 2px 3px; + height: 23px; + display: inline-block; + text-decoration: none; + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + -o-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + -ms-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25); + border-bottom: 1px solid rgba(0, 0, 0, 0.25); + border-radius: 5px 5px 5px 5px; + -moz-border-radius: 5px 0 0 5px; + -webkit-border-radius: 5px 5px 5px 5px; + -o-border-radius: 5px 5px 5px 5px; + -ms-border-radius: 5px 5px 5px 5px; +} + +.viewerToolbar-standaloneElement:active { + top: 1px; + position: relative; +} + +.viewerToolbar-standaloneElement:hover { + background: url("images/btn-cta-orangeleft.png") repeat-x scroll center -30px transparent; + cursor: pointer; +} + +.viewerToolbar-standaloneElement label { + cursor: pointer; +} diff --git a/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml b/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml index 0657d5ec63c..3e00dc9e9cb 100755 --- a/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml +++ b/java/com.sap.sailing.gwt.ui/WEB-INF/web.xml @@ -130,9 +130,8 @@ remoteLoggingServlet - /com.sap.sailing.gwt.home.Desktop/remote_logging - /com.sap.sailing.gwt.home.Mobile/remote_logging - /com.sap.sailing.gwt.ui.AdminConsole/remote_logging + /com.sap.sailing.gwt.Home/remote_logging + /com.sap.sailing.gwt.ui.AdminConsole/remote_logging /com.sap.sailing.gwt.ui.Leaderboard/remote_logging /com.sap.sailing.gwt.ui.Simulator/remote_logging /com.sap.sailing.gwt.ui.RaceBoard/remote_logging diff --git a/java/com.sap.sailing.gwt.ui/build.properties b/java/com.sap.sailing.gwt.ui/build.properties index 10e55f0cc1e..6e226b0d9b9 100755 --- a/java/com.sap.sailing.gwt.ui/build.properties +++ b/java/com.sap.sailing.gwt.ui/build.properties @@ -13,16 +13,18 @@ bin.includes = META-INF/,\ com.sap.sailing.gwt.ui.AdminConsole/,\ com.sap.sailing.gwt.ui.Leaderboard/,\ com.sap.sailing.gwt.ui.LeaderboardEditing/,\ - com.sap.sailing.gwt.home.Home/,\ + com.sap.sailing.gwt.Home/,\ com.sap.sailing.gwt.AutoPlay/,\ crossdomain.xml,\ images/,\ + CommonControls.css,\ RaceBoard.css,\ RaceBoard.html,\ Spectator.html,\ com.sap.sailing.gwt.ui.Spectator/,\ com.sap.sailing.gwt.ui.PolarSheets/,\ com.sap.sailing.gwt.ui.RaceBoard/,\ + highcharts/,\ Spectator.css,\ com.sap.sailing.gwt.ui.Simulator/,\ Simulator.html,\ @@ -37,6 +39,7 @@ bin.includes = META-INF/,\ BrowserUnsupported.html,\ PolarSheets.css,\ PolarSheets.html,\ + ViewerToolbar.css,\ com.sap.sailing.gwt.ui.DataMining/,\ DataMining.css,\ DataMining.html,\ @@ -48,7 +51,5 @@ bin.includes = META-INF/,\ AutoPlay.html,\ Home.css,\ Home.html,\ - HomeDesktop.html,\ - HomeMobile.html,\ SettingsDialog.css output.. = WEB-INF/classes/ diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/adapters/standalone-framework.js b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/standalone-framework.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/adapters/standalone-framework.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/adapters/standalone-framework.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/adapters/standalone-framework.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/standalone-framework.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/adapters/standalone-framework.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/adapters/standalone-framework.src.js diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-3d.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-3d.js similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-3d.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-3d.js diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-3d.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-3d.src.js similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-3d.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-3d.src.js diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-all.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-all.js similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-all.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-all.js diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-more.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.js similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-more.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.js diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-more.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.src.js similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts-more.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.src.js diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.js similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.js diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.src.js similarity index 100% rename from java/com.sap.sse.gwt/src/com/sap/sse/gwt/resources/highcharts/js/highcharts.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/canvas-tools.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/canvas-tools.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/canvas-tools.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/canvas-tools.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/data.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/data.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/data.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/data.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/drilldown.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/drilldown.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/drilldown.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/drilldown.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/drilldown.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/drilldown.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/drilldown.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/drilldown.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/exporting.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/exporting.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/exporting.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/exporting.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/funnel.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/funnel.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/funnel.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/funnel.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/funnel.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/funnel.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/funnel.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/funnel.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/heatmap.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/heatmap.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/heatmap.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/heatmap.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/heatmap.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/heatmap.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/heatmap.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/heatmap.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/no-data-to-display.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/no-data-to-display.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/no-data-to-display.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/no-data-to-display.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/no-data-to-display.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/no-data-to-display.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/no-data-to-display.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/no-data-to-display.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/solid-gauge.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/solid-gauge.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/solid-gauge.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/solid-gauge.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/solid-gauge.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/solid-gauge.src.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/modules/solid-gauge.src.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/modules/solid-gauge.src.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/dark-blue.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/dark-blue.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/dark-blue.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/dark-blue.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/dark-green.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/dark-green.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/dark-green.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/dark-green.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/dark-unica.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/dark-unica.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/dark-unica.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/dark-unica.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/gray.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/gray.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/gray.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/gray.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/grid-light.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/grid-light.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/grid-light.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/grid-light.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/grid.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/grid.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/grid.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/grid.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/sand-signika.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/sand-signika.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/sand-signika.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/sand-signika.js diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/skies.js b/java/com.sap.sailing.gwt.ui/highcharts/js/themes/skies.js similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/legacy/highcharts/js/themes/skies.js rename to java/com.sap.sailing.gwt.ui/highcharts/js/themes/skies.js diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/arrow-down-grey.png b/java/com.sap.sailing.gwt.ui/images/mobile/arrow-down-grey.png deleted file mode 100644 index 85a2c44730492545103fb6e0633e97dfdc1bb3b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 865 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEjKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pn}txArU1JzCKpT`MG+DDfvmMdKI|^K-CNkHWgMtW^QUpqC!P(PF}H9 zg{=};g%ywu64qBz04piUwpEJo4N!2-FG^J~)icpEP_pAvP*AWbN=dT{a&d!d2l8x{ zGD=Dctn~HE%ggo3jrH=2()A53EiLs8jP#9+bb%^#i!1X=5-W7`ij^UTz|3(;Elw`V zEGWs$&r<-Io0ybeT4JlD1hNPYpzh2qfLoMT4D}VzfBF@P1^R}12Kv}Em1L$NoQI+d zBm>a~_7%i38(`2_ITxiSmgE=BmTSintB$e@6$3ye)Ze#A{Nk!<{+phX2Zf2vwfLd2zYS zEysV))Sr+X^hA#DTivqET?~10hE3nN4ovy}c-z{wEc05o99@_!?$KLvP?l-sgmo6m z3-m9sr}LD!{(7{gVVein9McOTo~^}9a*Bm=w;p{py;o%Iy!CjG&YCwSnk%na%YQiM z5F(*8w{SP(K T{PnmhIN^J``njxgN@xNAvMerk diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/arrow-grey-right.png b/java/com.sap.sailing.gwt.ui/images/mobile/arrow-grey-right.png deleted file mode 100644 index cb174da3416d277c0962be9a796a00c4b36de7c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^oIotV!3-onPg`0Dq*&4&eH|GXHuiJ>Nn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N$@?z$e5NNY5k@0JY@F zZ0ZD30wqCy!3@VwiJre8aqXh`rK^{(h@ENZ5!MFEF(!GtyD)UH%6b4foCO|{#S9GG zLLkg|>2BR0prE~{i(?4Kb>DNId<+U4%ns#up8j8d^$1tdtd@YRHJ_jPJ>XD##3T0T x*NwWerwr+jS$SVP$b0G(q!PJ5lR0xM<9Si08G_$8T?ZP);OXk;vd$@?2>``CYhVBX diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/calender-icon-blue.svg b/java/com.sap.sailing.gwt.ui/images/mobile/calender-icon-blue.svg deleted file mode 100644 index f77d7ae8290..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/calender-icon-blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/fastest_sailor.svg b/java/com.sap.sailing.gwt.ui/images/mobile/fastest_sailor.svg deleted file mode 100644 index 20cef3f103a..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/fastest_sailor.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/icon_averageSpeed.svg b/java/com.sap.sailing.gwt.ui/images/mobile/icon_averageSpeed.svg deleted file mode 100644 index 74506b94bb7..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/icon_averageSpeed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/icon_racesCount.svg b/java/com.sap.sailing.gwt.ui/images/mobile/icon_racesCount.svg deleted file mode 100644 index 507373e4006..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/icon_racesCount.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/icon_regattasFought.svg b/java/com.sap.sailing.gwt.ui/images/mobile/icon_regattasFought.svg deleted file mode 100644 index a8b1c512965..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/icon_regattasFought.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/icon_trackedCount.svg b/java/com.sap.sailing.gwt.ui/images/mobile/icon_trackedCount.svg deleted file mode 100644 index 5fc22105de8..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/icon_trackedCount.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/logo-small@2x.png b/java/com.sap.sailing.gwt.ui/images/mobile/logo-small@2x.png deleted file mode 100644 index e5d2daf91f3962deb5be2991141b8145186e982a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6388 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 NVW?-STdnOB^*{MHr`-Sm diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/navigation-icon.svg b/java/com.sap.sailing.gwt.ui/images/mobile/navigation-icon.svg deleted file mode 100644 index b7038384ade..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/navigation-icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/quickfinder-arrow.svg b/java/com.sap.sailing.gwt.ui/images/mobile/quickfinder-arrow.svg deleted file mode 100644 index 5e83b054083..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/quickfinder-arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/raw_gps_fixes.svg b/java/com.sap.sailing.gwt.ui/images/mobile/raw_gps_fixes.svg deleted file mode 100644 index 0704a5542f9..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/raw_gps_fixes.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/search-icon.svg b/java/com.sap.sailing.gwt.ui/images/mobile/search-icon.svg deleted file mode 100644 index b7698516ea5..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/search-icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/strongest_wind.svg b/java/com.sap.sailing.gwt.ui/images/mobile/strongest_wind.svg deleted file mode 100644 index 7134bee2707..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/strongest_wind.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/java/com.sap.sailing.gwt.ui/images/mobile/sum_miles.svg b/java/com.sap.sailing.gwt.ui/images/mobile/sum_miles.svg deleted file mode 100644 index 3b99309ed1b..00000000000 --- a/java/com.sap.sailing.gwt.ui/images/mobile/sum_miles.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - diff --git a/java/com.sap.sailing.gwt.ui/js/video-js/demo.captions.vtt b/java/com.sap.sailing.gwt.ui/js/video-js/demo.captions.vtt new file mode 100644 index 00000000000..e598be19829 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/js/video-js/demo.captions.vtt @@ -0,0 +1,41 @@ +WEBVTT + +00:00.700 --> 00:04.110 +Captions describe all relevant audio for the hearing impaired. +[ Heroic music playing for a seagull ] + +00:04.500 --> 00:05.000 +[ Splash!!! ] + +00:05.100 --> 00:06.000 +[ Sploosh!!! ] + +00:08.000 --> 00:09.225 +[ Splash...splash...splash splash splash ] + +00:10.525 --> 00:11.255 +[ Splash, Sploosh again ] + +00:13.500 --> 00:14.984 +Dolphin: eeeEEEEEeeee! + +00:14.984 --> 00:16.984 +Dolphin: Squawk! eeeEEE? + +00:25.000 --> 00:28.284 +[ A whole ton of splashes ] + +00:29.500 --> 00:31.000 +Mine. Mine. Mine. + +00:34.300 --> 00:36.000 +Shark: Chomp + +00:36.800 --> 00:37.900 +Shark: CHOMP!!! + +00:37.861 --> 00:41.193 +EEEEEEOOOOOOOOOOWHALENOISE + +00:42.593 --> 00:45.611 +[ BIG SPLASH ] \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/js/video-js/demo.html b/java/com.sap.sailing.gwt.ui/js/video-js/demo.html new file mode 100644 index 00000000000..80937185652 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/js/video-js/demo.html @@ -0,0 +1,32 @@ + + + + Video.js | HTML5 Video Player + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.gwt.ui/js/video-js/video-js-sapsailing.css b/java/com.sap.sailing.gwt.ui/js/video-js/video-js-sapsailing.css index c30902104d4..5b97fb7d7f8 100644 --- a/java/com.sap.sailing.gwt.ui/js/video-js/video-js-sapsailing.css +++ b/java/com.sap.sailing.gwt.ui/js/video-js/video-js-sapsailing.css @@ -1 +1,3 @@ + +.video-js {padding-top: 56.25%} .vjs-fullscreen {padding-top: 0px} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/js/video-js/video-js.css b/java/com.sap.sailing.gwt.ui/js/video-js/video-js.css index 1628f48b4a8..b054a552378 100644 --- a/java/com.sap.sailing.gwt.ui/js/video-js/video-js.css +++ b/java/com.sap.sailing.gwt.ui/js/video-js/video-js.css @@ -1,6 +1,6 @@ /*! Video.js Default Styles (http://videojs.com) -Version 4.12.10 +Version 4.12.0 Create your own skin at http://designer.videojs.com */ /* SKIN @@ -37,7 +37,7 @@ The control icons are from a custom font. Each icon corresponds to a character padding: 0; /* background-color-with-alpha */ background-color: #333333; - background-color: rgba(51, 51, 51, 0.9); + background-color: rgba(51, 51, 51, 0.8); } .vjs-default-skin .vjs-slider:focus { /* box-shadow */ @@ -446,14 +446,18 @@ Positioning of the play button in the center or other corners can be done more easily in the skin designer. http://designer.videojs.com/ */ .vjs-default-skin .vjs-big-play-button { - left: 0.5em; - top: 0.5em; - font-size: 3em; + /* Center it horizontally */ + left: 50%; + margin-left: -2.75em; + /* Center it vertically */ + top: 50%; + margin-top: -1.8em; + font-size: 1.9em; display: block; z-index: 2; position: absolute; - width: 4em; - height: 2.6em; + width: 3.5em; + height: 1.6em; text-align: center; vertical-align: middle; cursor: pointer; @@ -461,12 +465,12 @@ easily in the skin designer. http://designer.videojs.com/ /* Need a slightly gray bg so it can be seen on black backgrounds */ /* background-color-with-alpha */ background-color: #07141e; - background-color: rgba(7, 20, 30, 0.7); - border: 0.1em solid #3b4249; + background-color: rgba(7, 20, 30, 0.5); + border: 1px solid #3b4249; /* border-radius */ - -webkit-border-radius: 0.8em; - -moz-border-radius: 0.8em; - border-radius: 0.8em; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; /* box-shadow */ -webkit-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25); -moz-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25); @@ -481,10 +485,10 @@ easily in the skin designer. http://designer.videojs.com/ .vjs-default-skin.vjs-big-play-centered .vjs-big-play-button { /* Center it horizontally */ left: 50%; - margin-left: -2.1em; + margin-left: -1.5em; /* Center it vertically */ top: 50%; - margin-top: -1.4000000000000001em; + margin-top: -1.3em; } /* Hide if controls are disabled */ .vjs-default-skin.vjs-controls-disabled .vjs-big-play-button { @@ -522,7 +526,7 @@ easily in the skin designer. http://designer.videojs.com/ /* In order to center the play icon vertically we need to set the line height to the same as the button height */ - line-height: 2.6em; + line-height: 1.6em; text-shadow: 0.05em 0.05em 0.1em #000; text-align: center /* Needed for IE8 */; position: absolute; @@ -868,7 +872,6 @@ body.vjs-full-window { background-repeat: no-repeat; background-position: 50% 50%; background-size: contain; - background-color: #000000; cursor: pointer; margin: 0; padding: 0; @@ -1009,3 +1012,4 @@ body.vjs-full-window { /* ----------------------------------------------------------------------------- The original source of this file lives at https://github.com/videojs/video.js/blob/master/src/css/video-js.less */ + diff --git a/java/com.sap.sailing.gwt.ui/js/video-js/video-js.less b/java/com.sap.sailing.gwt.ui/js/video-js/video-js.less index 8c2576b3503..fc43aee4224 100644 --- a/java/com.sap.sailing.gwt.ui/js/video-js/video-js.less +++ b/java/com.sap.sailing.gwt.ui/js/video-js/video-js.less @@ -924,7 +924,6 @@ body.vjs-full-window { background-repeat: no-repeat; background-position: 50% 50%; background-size: contain; - background-color: #000000; cursor: pointer; margin: 0; padding: 0; diff --git a/java/com.sap.sailing.gwt.ui/js/video-js/video-js.min.css b/java/com.sap.sailing.gwt.ui/js/video-js/video-js.min.css index aae733bc263..7f0a749e4e7 100644 --- a/java/com.sap.sailing.gwt.ui/js/video-js/video-js.min.css +++ b/java/com.sap.sailing.gwt.ui/js/video-js/video-js.min.css @@ -1,5 +1,5 @@ /*! Video.js Default Styles (http://videojs.com) -Version 4.12.10 +Version 4.12.6 Create your own skin at http://designer.videojs.com -*/.vjs-default-skin{color:#ccc}@font-face{font-family:VideoJS;src:url(font/vjs.eot);src:url(font/vjs.eot?#iefix) format('embedded-opentype'),url(font/vjs.woff) format('woff'),url(font/vjs.ttf) format('truetype'),url(font/vjs.svg#icomoon) format('svg');font-weight:400;font-style:normal}.vjs-default-skin .vjs-slider{outline:0;position:relative;cursor:pointer;padding:0;background-color:#333;background-color:rgba(51,51,51,.9)}.vjs-default-skin .vjs-slider:focus{-webkit-box-shadow:0 0 2em #fff;-moz-box-shadow:0 0 2em #fff;box-shadow:0 0 2em #fff}.vjs-default-skin .vjs-slider-handle{position:absolute;left:0;top:0}.vjs-default-skin .vjs-slider-handle:before{content:"\e009";font-family:VideoJS;font-size:1em;line-height:1;text-align:center;text-shadow:0 0 1em #fff;position:absolute;top:0;left:0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.vjs-default-skin .vjs-control-bar{display:none;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#07141e;background-color:rgba(7,20,30,.7)}.vjs-default-skin.vjs-has-started .vjs-control-bar{display:block;visibility:visible;opacity:1;-webkit-transition:visibility .1s,opacity .1s;-moz-transition:visibility .1s,opacity .1s;-o-transition:visibility .1s,opacity .1s;transition:visibility .1s,opacity .1s}.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{display:block;visibility:hidden;opacity:0;-webkit-transition:visibility 1s,opacity 1s;-moz-transition:visibility 1s,opacity 1s;-o-transition:visibility 1s,opacity 1s;transition:visibility 1s,opacity 1s}.vjs-default-skin.vjs-controls-disabled .vjs-control-bar{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-control-bar{display:none}.vjs-default-skin.vjs-error .vjs-control-bar{display:none}.vjs-audio.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}@media \0screen{.vjs-default-skin.vjs-user-inactive.vjs-playing .vjs-control-bar :before{content:""}}.vjs-default-skin .vjs-control{outline:0;position:relative;float:left;text-align:center;margin:0;padding:0;height:3em;width:4em}.vjs-default-skin .vjs-control:before{font-family:VideoJS;font-size:1.5em;line-height:2;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,.5)}.vjs-default-skin .vjs-control:focus:before,.vjs-default-skin .vjs-control:hover:before{text-shadow:0 0 1em #fff}.vjs-default-skin .vjs-control:focus{}.vjs-default-skin .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-default-skin .vjs-play-control{width:5em;cursor:pointer}.vjs-default-skin .vjs-play-control:before{content:"\e001"}.vjs-default-skin.vjs-playing .vjs-play-control:before{content:"\e002"}.vjs-default-skin .vjs-playback-rate .vjs-playback-rate-value{font-size:1.5em;line-height:2;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,.5)}.vjs-default-skin .vjs-playback-rate.vjs-menu-button .vjs-menu .vjs-menu-content{width:4em;left:-2em;list-style:none}.vjs-default-skin .vjs-mute-control,.vjs-default-skin .vjs-volume-menu-button{cursor:pointer;float:right}.vjs-default-skin .vjs-mute-control:before,.vjs-default-skin .vjs-volume-menu-button:before{content:"\e006"}.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before{content:"\e003"}.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before{content:"\e004"}.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before{content:"\e005"}.vjs-default-skin .vjs-volume-control{width:5em;float:right}.vjs-default-skin .vjs-volume-bar{width:5em;height:.6em;margin:1.1em auto 0}.vjs-default-skin .vjs-volume-level{position:absolute;top:0;left:0;height:.5em;width:100%;background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-volume-bar .vjs-volume-handle{width:.5em;height:.5em;left:4.5em}.vjs-default-skin .vjs-volume-handle:before{font-size:.9em;top:-.2em;left:-.2em;width:1em;height:1em}.vjs-default-skin .vjs-volume-menu-button .vjs-menu{display:block;width:0;height:0;border-top-color:transparent}.vjs-default-skin .vjs-volume-menu-button .vjs-menu .vjs-menu-content{height:0;width:0}.vjs-default-skin .vjs-volume-menu-button:hover .vjs-menu,.vjs-default-skin .vjs-volume-menu-button .vjs-menu.vjs-lock-showing{border-top-color:rgba(7,40,50,.5)}.vjs-default-skin .vjs-volume-menu-button:hover .vjs-menu .vjs-menu-content,.vjs-default-skin .vjs-volume-menu-button .vjs-menu.vjs-lock-showing .vjs-menu-content{height:2.9em;width:10em}.vjs-default-skin .vjs-progress-control{position:absolute;left:0;right:0;width:auto;font-size:.3em;height:1em;top:-1em;-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin:hover .vjs-progress-control{font-size:.9em;-webkit-transition:all .2s;-moz-transition:all .2s;-o-transition:all .2s;transition:all .2s}.vjs-default-skin .vjs-progress-holder{height:100%}.vjs-default-skin .vjs-progress-holder .vjs-play-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress div{position:absolute;display:block;height:100%;margin:0;padding:0;width:0;left:0;top:0}.vjs-default-skin .vjs-play-progress{background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-load-progress{background:#646464;background:rgba(255,255,255,.2)}.vjs-default-skin .vjs-load-progress div{background:#787878;background:rgba(255,255,255,.1)}.vjs-default-skin .vjs-seek-handle{width:1.5em;height:100%}.vjs-default-skin .vjs-seek-handle:before{padding-top:.1em}.vjs-default-skin.vjs-live .vjs-time-controls,.vjs-default-skin.vjs-live .vjs-time-divider,.vjs-default-skin.vjs-live .vjs-progress-control{display:none}.vjs-default-skin.vjs-live .vjs-live-display{display:block}.vjs-default-skin .vjs-live-display{display:none;font-size:1em;line-height:3em}.vjs-default-skin .vjs-time-controls{font-size:1em;line-height:3em}.vjs-default-skin .vjs-current-time{float:left}.vjs-default-skin .vjs-duration{float:left}.vjs-default-skin .vjs-remaining-time{display:none;float:left}.vjs-time-divider{float:left;line-height:3em}.vjs-default-skin .vjs-fullscreen-control{width:3.8em;cursor:pointer;float:right}.vjs-default-skin .vjs-fullscreen-control:before{content:"\e000"}.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before{content:"\e00b"}.vjs-default-skin .vjs-big-play-button{left:.5em;top:.5em;font-size:3em;display:block;z-index:2;position:absolute;width:4em;height:2.6em;text-align:center;vertical-align:middle;cursor:pointer;opacity:1;background-color:#07141e;background-color:rgba(7,20,30,.7);border:.1em solid #3b4249;-webkit-border-radius:.8em;-moz-border-radius:.8em;border-radius:.8em;-webkit-box-shadow:0 0 1em rgba(255,255,255,.25);-moz-box-shadow:0 0 1em rgba(255,255,255,.25);box-shadow:0 0 1em rgba(255,255,255,.25);-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin.vjs-big-play-centered .vjs-big-play-button{left:50%;margin-left:-2.1em;top:50%;margin-top:-1.4000000000000001em}.vjs-default-skin.vjs-controls-disabled .vjs-big-play-button{display:none}.vjs-default-skin.vjs-has-started .vjs-big-play-button{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-default-skin:hover .vjs-big-play-button,.vjs-default-skin .vjs-big-play-button:focus{outline:0;border-color:#fff;background-color:#505050;background-color:rgba(50,50,50,.75);-webkit-box-shadow:0 0 3em #fff;-moz-box-shadow:0 0 3em #fff;box-shadow:0 0 3em #fff;-webkit-transition:all 0s;-moz-transition:all 0s;-o-transition:all 0s;transition:all 0s}.vjs-default-skin .vjs-big-play-button:before{content:"\e001";font-family:VideoJS;line-height:2.6em;text-shadow:.05em .05em .1em #000;text-align:center;position:absolute;left:0;width:100%;height:100%}.vjs-error .vjs-big-play-button{display:none}.vjs-error-display{display:none}.vjs-error .vjs-error-display{display:block;position:absolute;left:0;top:0;width:100%;height:100%}.vjs-error .vjs-error-display:before{content:'X';font-family:Arial;font-size:4em;color:#666;line-height:1;text-shadow:.05em .05em .1em #000;text-align:center;vertical-align:middle;position:absolute;left:0;top:50%;margin-top:-.5em;width:100%}.vjs-error-display div{position:absolute;bottom:1em;right:0;left:0;font-size:1.4em;text-align:center;padding:3px;background:#000;background:rgba(0,0,0,.5)}.vjs-error-display a,.vjs-error-display a:visited{color:#F4A460}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;font-size:4em;line-height:1;width:1em;height:1em;margin-left:-.5em;margin-top:-.5em;opacity:.75}.vjs-waiting .vjs-loading-spinner,.vjs-seeking .vjs-loading-spinner{display:block;-webkit-animation:spin 1.5s infinite linear;-moz-animation:spin 1.5s infinite linear;-o-animation:spin 1.5s infinite linear;animation:spin 1.5s infinite linear}.vjs-error .vjs-loading-spinner{display:none;-webkit-animation:none;-moz-animation:none;-o-animation:none;animation:none}.vjs-default-skin .vjs-loading-spinner:before{content:"\e01e";font-family:VideoJS;position:absolute;top:0;left:0;width:1em;height:1em;text-align:center;text-shadow:0 0 .1em #000}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.vjs-default-skin .vjs-menu-button{float:right;cursor:pointer}.vjs-default-skin .vjs-menu{display:none;position:absolute;bottom:0;left:0;width:0;height:0;margin-bottom:3em;border-left:2em solid transparent;border-right:2em solid transparent;border-top:1.55em solid #000;border-top-color:rgba(7,40,50,.5)}.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;position:absolute;width:10em;bottom:1.5em;max-height:15em;overflow:auto;left:-5em;background-color:#07141e;background-color:rgba(7,20,30,.7);-webkit-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);-moz-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);box-shadow:-.2em -.2em .3em rgba(255,255,255,.2)}.vjs-default-skin .vjs-menu-button:hover .vjs-control-content .vjs-menu,.vjs-default-skin .vjs-control-content .vjs-menu.vjs-lock-showing{display:block}.vjs-default-skin.vjs-scrubbing .vjs-menu-button:hover .vjs-control-content .vjs-menu{display:none}.vjs-default-skin .vjs-menu-button ul li{list-style:none;margin:0;padding:.3em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.vjs-default-skin .vjs-menu-button ul li.vjs-selected{background-color:#000}.vjs-default-skin .vjs-menu-button ul li:focus,.vjs-default-skin .vjs-menu-button ul li:hover,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover{outline:0;color:#111;background-color:#fff;background-color:rgba(255,255,255,.75);-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em;font-weight:700;cursor:default}.vjs-default-skin .vjs-subtitles-button:before{content:"\e00c"}.vjs-default-skin .vjs-captions-button:before{content:"\e008"}.vjs-default-skin .vjs-chapters-button:before{content:"\e00c"}.vjs-default-skin .vjs-chapters-button.vjs-menu-button .vjs-menu .vjs-menu-content{width:24em;left:-12em}.vjs-default-skin .vjs-captions-button:focus .vjs-control-content:before,.vjs-default-skin .vjs-captions-button:hover .vjs-control-content:before{-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js{background-color:#000;position:relative;padding:0;font-size:10px;vertical-align:middle;font-weight:400;font-style:normal;font-family:Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}.video-js:-moz-full-screen{position:absolute}body.vjs-full-window{padding:0;margin:0;height:100%;overflow-y:auto}.video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0;width:100%!important;height:100%!important;_position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-poster{background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0}.vjs-poster img{display:block;margin:0 auto;max-height:100%;padding:0;width:100%}.video-js.vjs-has-started .vjs-poster{display:none}.video-js.vjs-audio.vjs-has-started .vjs-poster{display:block}.video-js.vjs-controls-disabled .vjs-poster{display:none}.video-js.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-text-track-display{position:absolute;top:0;left:0;bottom:3em;right:0;pointer-events:none}.vjs-caption-settings{position:relative;top:1em;background-color:#000;opacity:.75;color:#FFF;margin:0 auto;padding:.5em;height:15em;font-family:Arial,Helvetica,sans-serif;font-size:12px;width:40em}.vjs-caption-settings .vjs-tracksettings{top:0;bottom:2em;left:0;right:0;position:absolute;overflow:auto}.vjs-caption-settings .vjs-tracksettings-colors,.vjs-caption-settings .vjs-tracksettings-font{float:left}.vjs-caption-settings .vjs-tracksettings-colors:after,.vjs-caption-settings .vjs-tracksettings-font:after,.vjs-caption-settings .vjs-tracksettings-controls:after{clear:both}.vjs-caption-settings .vjs-tracksettings-controls{position:absolute;bottom:1em;right:1em}.vjs-caption-settings .vjs-tracksetting{margin:5px;padding:3px;min-height:40px}.vjs-caption-settings .vjs-tracksetting label{display:block;width:100px;margin-bottom:5px}.vjs-caption-settings .vjs-tracksetting span{display:inline;margin-left:5px}.vjs-caption-settings .vjs-tracksetting>div{margin-bottom:5px;min-height:20px}.vjs-caption-settings .vjs-tracksetting>div:last-child{margin-bottom:0;padding-bottom:0;min-height:0}.vjs-caption-settings label>input{margin-right:10px}.vjs-caption-settings input[type=button]{width:40px;height:40px}.vjs-hidden{display:none!important}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:2em;color:#ccc;background-color:#333;font-size:1.8em;font-family:Arial,sans-serif;text-align:center;width:30em;height:15em;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#F4A460} \ No newline at end of file +*/.vjs-default-skin{color:#ccc}@font-face{font-family:VideoJS;src:url(font/vjs.eot);src:url(font/vjs.eot?#iefix) format('embedded-opentype'),url(font/vjs.woff) format('woff'),url(font/vjs.ttf) format('truetype'),url(font/vjs.svg#icomoon) format('svg');font-weight:400;font-style:normal}.vjs-default-skin .vjs-slider{outline:0;position:relative;cursor:pointer;padding:0;background-color:#333;background-color:rgba(51,51,51,.9)}.vjs-default-skin .vjs-slider:focus{-webkit-box-shadow:0 0 2em #fff;-moz-box-shadow:0 0 2em #fff;box-shadow:0 0 2em #fff}.vjs-default-skin .vjs-slider-handle{position:absolute;left:0;top:0}.vjs-default-skin .vjs-slider-handle:before{content:"\e009";font-family:VideoJS;font-size:1em;line-height:1;text-align:center;text-shadow:0 0 1em #fff;position:absolute;top:0;left:0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.vjs-default-skin .vjs-control-bar{display:none;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#07141e;background-color:rgba(7,20,30,.7)}.vjs-default-skin.vjs-has-started .vjs-control-bar{display:block;visibility:visible;opacity:1;-webkit-transition:visibility .1s,opacity .1s;-moz-transition:visibility .1s,opacity .1s;-o-transition:visibility .1s,opacity .1s;transition:visibility .1s,opacity .1s}.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{display:block;visibility:hidden;opacity:0;-webkit-transition:visibility 1s,opacity 1s;-moz-transition:visibility 1s,opacity 1s;-o-transition:visibility 1s,opacity 1s;transition:visibility 1s,opacity 1s}.vjs-default-skin.vjs-controls-disabled .vjs-control-bar{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-control-bar{display:none}.vjs-default-skin.vjs-error .vjs-control-bar{display:none}.vjs-audio.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}@media \0screen{.vjs-default-skin.vjs-user-inactive.vjs-playing .vjs-control-bar :before{content:""}}.vjs-default-skin .vjs-control{outline:0;position:relative;float:left;text-align:center;margin:0;padding:0;height:3em;width:4em}.vjs-default-skin .vjs-control:before{font-family:VideoJS;font-size:1.5em;line-height:2;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,.5)}.vjs-default-skin .vjs-control:focus:before,.vjs-default-skin .vjs-control:hover:before{text-shadow:0 0 1em #fff}.vjs-default-skin .vjs-control:focus{}.vjs-default-skin .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-default-skin .vjs-play-control{width:5em;cursor:pointer}.vjs-default-skin .vjs-play-control:before{content:"\e001"}.vjs-default-skin.vjs-playing .vjs-play-control:before{content:"\e002"}.vjs-default-skin .vjs-playback-rate .vjs-playback-rate-value{font-size:1.5em;line-height:2;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,.5)}.vjs-default-skin .vjs-playback-rate.vjs-menu-button .vjs-menu .vjs-menu-content{width:4em;left:-2em;list-style:none}.vjs-default-skin .vjs-mute-control,.vjs-default-skin .vjs-volume-menu-button{cursor:pointer;float:right}.vjs-default-skin .vjs-mute-control:before,.vjs-default-skin .vjs-volume-menu-button:before{content:"\e006"}.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before{content:"\e003"}.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before{content:"\e004"}.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before{content:"\e005"}.vjs-default-skin .vjs-volume-control{width:5em;float:right}.vjs-default-skin .vjs-volume-bar{width:5em;height:.6em;margin:1.1em auto 0}.vjs-default-skin .vjs-volume-level{position:absolute;top:0;left:0;height:.5em;width:100%;background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-volume-bar .vjs-volume-handle{width:.5em;height:.5em;left:4.5em}.vjs-default-skin .vjs-volume-handle:before{font-size:.9em;top:-.2em;left:-.2em;width:1em;height:1em}.vjs-default-skin .vjs-volume-menu-button .vjs-menu{display:block;width:0;height:0;border-top-color:transparent}.vjs-default-skin .vjs-volume-menu-button .vjs-menu .vjs-menu-content{height:0;width:0}.vjs-default-skin .vjs-volume-menu-button:hover .vjs-menu,.vjs-default-skin .vjs-volume-menu-button .vjs-menu.vjs-lock-showing{border-top-color:rgba(7,40,50,.5)}.vjs-default-skin .vjs-volume-menu-button:hover .vjs-menu .vjs-menu-content,.vjs-default-skin .vjs-volume-menu-button .vjs-menu.vjs-lock-showing .vjs-menu-content{height:2.9em;width:10em}.vjs-default-skin .vjs-progress-control{position:absolute;left:0;right:0;width:auto;font-size:.3em;height:1em;top:-1em;-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin:hover .vjs-progress-control{font-size:.9em;-webkit-transition:all .2s;-moz-transition:all .2s;-o-transition:all .2s;transition:all .2s}.vjs-default-skin .vjs-progress-holder{height:100%}.vjs-default-skin .vjs-progress-holder .vjs-play-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress div{position:absolute;display:block;height:100%;margin:0;padding:0;width:0;left:0;top:0}.vjs-default-skin .vjs-play-progress{background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-load-progress{background:#646464;background:rgba(255,255,255,.2)}.vjs-default-skin .vjs-load-progress div{background:#787878;background:rgba(255,255,255,.1)}.vjs-default-skin .vjs-seek-handle{width:1.5em;height:100%}.vjs-default-skin .vjs-seek-handle:before{padding-top:.1em}.vjs-default-skin.vjs-live .vjs-time-controls,.vjs-default-skin.vjs-live .vjs-time-divider,.vjs-default-skin.vjs-live .vjs-progress-control{display:none}.vjs-default-skin.vjs-live .vjs-live-display{display:block}.vjs-default-skin .vjs-live-display{display:none;font-size:1em;line-height:3em}.vjs-default-skin .vjs-time-controls{font-size:1em;line-height:3em}.vjs-default-skin .vjs-current-time{float:left}.vjs-default-skin .vjs-duration{float:left}.vjs-default-skin .vjs-remaining-time{display:none;float:left}.vjs-time-divider{float:left;line-height:3em}.vjs-default-skin .vjs-fullscreen-control{width:3.8em;cursor:pointer;float:right}.vjs-default-skin .vjs-fullscreen-control:before{content:"\e000"}.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before{content:"\e00b"}.vjs-default-skin .vjs-big-play-button{left:.5em;top:.5em;font-size:3em;display:block;z-index:2;position:absolute;width:4em;height:2.6em;text-align:center;vertical-align:middle;cursor:pointer;opacity:1;background-color:#07141e;background-color:rgba(7,20,30,.7);border:.1em solid #3b4249;-webkit-border-radius:.8em;-moz-border-radius:.8em;border-radius:.8em;-webkit-box-shadow:0 0 1em rgba(255,255,255,.25);-moz-box-shadow:0 0 1em rgba(255,255,255,.25);box-shadow:0 0 1em rgba(255,255,255,.25);-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin.vjs-big-play-centered .vjs-big-play-button{left:50%;margin-left:-2.1em;top:50%;margin-top:-1.4000000000000001em}.vjs-default-skin.vjs-controls-disabled .vjs-big-play-button{display:none}.vjs-default-skin.vjs-has-started .vjs-big-play-button{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-default-skin:hover .vjs-big-play-button,.vjs-default-skin .vjs-big-play-button:focus{outline:0;border-color:#fff;background-color:#505050;background-color:rgba(50,50,50,.75);-webkit-box-shadow:0 0 3em #fff;-moz-box-shadow:0 0 3em #fff;box-shadow:0 0 3em #fff;-webkit-transition:all 0s;-moz-transition:all 0s;-o-transition:all 0s;transition:all 0s}.vjs-default-skin .vjs-big-play-button:before{content:"\e001";font-family:VideoJS;line-height:2.6em;text-shadow:.05em .05em .1em #000;text-align:center;position:absolute;left:0;width:100%;height:100%}.vjs-error .vjs-big-play-button{display:none}.vjs-error-display{display:none}.vjs-error .vjs-error-display{display:block;position:absolute;left:0;top:0;width:100%;height:100%}.vjs-error .vjs-error-display:before{content:'X';font-family:Arial;font-size:4em;color:#666;line-height:1;text-shadow:.05em .05em .1em #000;text-align:center;vertical-align:middle;position:absolute;left:0;top:50%;margin-top:-.5em;width:100%}.vjs-error-display div{position:absolute;bottom:1em;right:0;left:0;font-size:1.4em;text-align:center;padding:3px;background:#000;background:rgba(0,0,0,.5)}.vjs-error-display a,.vjs-error-display a:visited{color:#F4A460}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;font-size:4em;line-height:1;width:1em;height:1em;margin-left:-.5em;margin-top:-.5em;opacity:.75}.vjs-waiting .vjs-loading-spinner,.vjs-seeking .vjs-loading-spinner{display:block;-webkit-animation:spin 1.5s infinite linear;-moz-animation:spin 1.5s infinite linear;-o-animation:spin 1.5s infinite linear;animation:spin 1.5s infinite linear}.vjs-error .vjs-loading-spinner{display:none;-webkit-animation:none;-moz-animation:none;-o-animation:none;animation:none}.vjs-default-skin .vjs-loading-spinner:before{content:"\e01e";font-family:VideoJS;position:absolute;top:0;left:0;width:1em;height:1em;text-align:center;text-shadow:0 0 .1em #000}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.vjs-default-skin .vjs-menu-button{float:right;cursor:pointer}.vjs-default-skin .vjs-menu{display:none;position:absolute;bottom:0;left:0;width:0;height:0;margin-bottom:3em;border-left:2em solid transparent;border-right:2em solid transparent;border-top:1.55em solid #000;border-top-color:rgba(7,40,50,.5)}.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;position:absolute;width:10em;bottom:1.5em;max-height:15em;overflow:auto;left:-5em;background-color:#07141e;background-color:rgba(7,20,30,.7);-webkit-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);-moz-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);box-shadow:-.2em -.2em .3em rgba(255,255,255,.2)}.vjs-default-skin .vjs-menu-button:hover .vjs-control-content .vjs-menu,.vjs-default-skin .vjs-control-content .vjs-menu.vjs-lock-showing{display:block}.vjs-default-skin.vjs-scrubbing .vjs-menu-button:hover .vjs-control-content .vjs-menu{display:none}.vjs-default-skin .vjs-menu-button ul li{list-style:none;margin:0;padding:.3em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.vjs-default-skin .vjs-menu-button ul li.vjs-selected{background-color:#000}.vjs-default-skin .vjs-menu-button ul li:focus,.vjs-default-skin .vjs-menu-button ul li:hover,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover{outline:0;color:#111;background-color:#fff;background-color:rgba(255,255,255,.75);-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em;font-weight:700;cursor:default}.vjs-default-skin .vjs-subtitles-button:before{content:"\e00c"}.vjs-default-skin .vjs-captions-button:before{content:"\e008"}.vjs-default-skin .vjs-chapters-button:before{content:"\e00c"}.vjs-default-skin .vjs-chapters-button.vjs-menu-button .vjs-menu .vjs-menu-content{width:24em;left:-12em}.vjs-default-skin .vjs-captions-button:focus .vjs-control-content:before,.vjs-default-skin .vjs-captions-button:hover .vjs-control-content:before{-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js{background-color:#000;position:relative;padding:0;font-size:10px;vertical-align:middle;font-weight:400;font-style:normal;font-family:Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}.video-js:-moz-full-screen{position:absolute}body.vjs-full-window{padding:0;margin:0;height:100%;overflow-y:auto}.video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0;width:100%!important;height:100%!important;_position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-poster{background-repeat:no-repeat;background-position:50% 50%;background-size:contain;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0}.vjs-poster img{display:block;margin:0 auto;max-height:100%;padding:0;width:100%}.video-js.vjs-has-started .vjs-poster{display:none}.video-js.vjs-audio.vjs-has-started .vjs-poster{display:block}.video-js.vjs-controls-disabled .vjs-poster{display:none}.video-js.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-text-track-display{position:absolute;top:0;left:0;bottom:3em;right:0;pointer-events:none}.vjs-caption-settings{position:relative;top:1em;background-color:#000;opacity:.75;color:#FFF;margin:0 auto;padding:.5em;height:15em;font-family:Arial,Helvetica,sans-serif;font-size:12px;width:40em}.vjs-caption-settings .vjs-tracksettings{top:0;bottom:2em;left:0;right:0;position:absolute;overflow:auto}.vjs-caption-settings .vjs-tracksettings-colors,.vjs-caption-settings .vjs-tracksettings-font{float:left}.vjs-caption-settings .vjs-tracksettings-colors:after,.vjs-caption-settings .vjs-tracksettings-font:after,.vjs-caption-settings .vjs-tracksettings-controls:after{clear:both}.vjs-caption-settings .vjs-tracksettings-controls{position:absolute;bottom:1em;right:1em}.vjs-caption-settings .vjs-tracksetting{margin:5px;padding:3px;min-height:40px}.vjs-caption-settings .vjs-tracksetting label{display:block;width:100px;margin-bottom:5px}.vjs-caption-settings .vjs-tracksetting span{display:inline;margin-left:5px}.vjs-caption-settings .vjs-tracksetting>div{margin-bottom:5px;min-height:20px}.vjs-caption-settings .vjs-tracksetting>div:last-child{margin-bottom:0;padding-bottom:0;min-height:0}.vjs-caption-settings label>input{margin-right:10px}.vjs-caption-settings input[type=button]{width:40px;height:40px}.vjs-hidden{display:none!important}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible}.vjs-no-js{padding:2em;color:#ccc;background-color:#333;font-size:1.8em;font-family:Arial,sans-serif;text-align:center;width:30em;height:15em;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#F4A460} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/js/video-js/video-js.swf b/java/com.sap.sailing.gwt.ui/js/video-js/video-js.swf index 738dab777a193a48ff805f447fb7496b31cabbe7..1b0d3f39ab498702a052a6905c463376b5d7f0b1 100644 GIT binary patch literal 17202 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 FFhZ*5?b-kU literal 17485 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