mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-19 18:50:03 +00:00
solved merge conlficts after ribdashboard merge
This commit is contained in:
commit
9d69655caf
826 files changed
+12737
-14630
No files matched your search
@@ -27,46 +27,6 @@
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.bottomnotification {
|
||||
position: absolute !important;
|
||||
opacity: 0.9;
|
||||
background-color: #F0AB00;
|
||||
height: 0pt;
|
||||
line-height: 0pt;
|
||||
width: 100%;
|
||||
bottom: 0pt;
|
||||
text-align: center;
|
||||
font-size: 15pt;
|
||||
line-height: 30pt;
|
||||
color: black;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.bottomnotificationshow {
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
|
||||
/* older webkit */
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
/* custom */
|
||||
height: 30pt;
|
||||
line-height: 30pt;
|
||||
}
|
||||
|
||||
.bottomnotificationhidden {
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
|
||||
/* older webkit */
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
/* custom */
|
||||
height: 0pt;
|
||||
line-height: 0pt;
|
||||
}
|
||||
|
||||
.eventLogo {
|
||||
position: absolute;
|
||||
right: 12.5px;
|
||||
@@ -74,62 +34,3 @@
|
||||
height: 22.5pt;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.wrongOrientationNotification {
|
||||
position: absolute !important;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
background-color: white;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.wrongOrientationNotification_shown {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-right: -100px;
|
||||
margin-top: -100px;
|
||||
border-radius: 100px;
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
|
||||
/* older webkit */
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.wrongOrientationNotification_hidden {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
marin-right: 0px;
|
||||
margin-top: 0px;
|
||||
border-radius: 0px;
|
||||
overflow: hidden;
|
||||
-webkit-transition: all 300ms;
|
||||
/* older webkit */
|
||||
-webkit-transition: all 300ms;
|
||||
-moz-transition: all 300ms;
|
||||
-o-transition: all 300ms;
|
||||
transition: all 300ms;
|
||||
opacity: 0.0;
|
||||
}
|
||||
|
||||
.wrongOrientationNotification_logo {
|
||||
max-width: 40%;
|
||||
max-height: 40%;
|
||||
margin: 30%;
|
||||
margin-top: 23%
|
||||
}
|
||||
|
||||
.wrongOrientationNotification_text {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
top: 76%;
|
||||
line-height: 10px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
color: grey;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
}
|
||||
@@ -43,5 +43,5 @@
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9998 com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread -Xmx2048m"/>
|
||||
</launchConfiguration>
|
||||
@@ -43,5 +43,5 @@
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread -Xmx2048m"/>
|
||||
</launchConfiguration>
|
||||
+1
-2
@@ -41,9 +41,8 @@ public class RibDashboardEntryPoint extends AbstractEntryPoint<StringMessages> {
|
||||
applyMGWTSettings();
|
||||
RibDashboardPanel ribDashboardPanel = new RibDashboardPanel(ribdashboardService, sailingService, dataRetriever);
|
||||
RootLayoutPanel.get().add(ribDashboardPanel);
|
||||
WindBotDataRetriever windBotDataRetriever = new WindBotDataRetriever(sailingService);
|
||||
WindBotDataRetriever windBotDataRetriever = new WindBotDataRetriever(ribdashboardService, sailingService);
|
||||
windBotDataRetriever.addNumberOfWindBotsChangeListeners(ribDashboardPanel);
|
||||
dataRetriever.addRaceSelectionChangeListener(windBotDataRetriever);
|
||||
Timer dashboardTimer = new Timer(PlayModes.Live);
|
||||
dashboardTimer.setRefreshInterval(DASHBOARD_RERFRESH_INTERVAL);
|
||||
dashboardTimer.addTimeListener(windBotDataRetriever);
|
||||
|
||||
-4
@@ -2,8 +2,6 @@ package com.sap.sailing.dashboards.gwt.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
@@ -45,7 +43,6 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
|
||||
}
|
||||
|
||||
private static RootUiBinder uiBinder = GWT.create(RootUiBinder.class);
|
||||
private static final Logger logger = Logger.getLogger(RibDashboardPanel.class.getName());
|
||||
|
||||
@UiField
|
||||
RibDashboardPanelStyle style;
|
||||
@@ -179,7 +176,6 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
|
||||
@Override
|
||||
public void numberOfWindBotsChanged(List<String> windBotIDs,
|
||||
WindBotDataRetrieverProvider windBotDataRetrieverProvider) {
|
||||
logger.log(Level.INFO, "Number of Windbots changed");
|
||||
initWindBotComponents(windBotIDs, windBotDataRetrieverProvider);
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -7,10 +7,13 @@ import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
|
||||
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.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
|
||||
public interface RibDashboardService extends RemoteService {
|
||||
RibDashboardRaceInfoDTO getLiveRaceInfo(String leaderboardName) throws NoWindException;
|
||||
RibDashboardRaceInfoDTO getLiveRaceInfo(String leaderboardName) throws NoWindException;
|
||||
|
||||
RegattaAndRaceIdentifier getIDFromRaceThatTakesWindFixesNow(String leaderboardName);
|
||||
|
||||
List<StartAnalysisDTO> getStartAnalysisListForCompetitorIDAndLeaderboardName(String competitorIdAsString, String leaderboardName);
|
||||
|
||||
|
||||
+4
@@ -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.StartlineAdvantagesWithMaxAndAverageDTO;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
|
||||
public interface RibDashboardServiceAsync {
|
||||
@@ -17,4 +18,7 @@ public interface RibDashboardServiceAsync {
|
||||
void getCompetitorsInLeaderboard(String leaderboardName, AsyncCallback<List<CompetitorDTO>> callback);
|
||||
|
||||
void getAdvantagesOnStartline(String leaderboardName, AsyncCallback<StartlineAdvantagesWithMaxAndAverageDTO> callback);
|
||||
|
||||
void getIDFromRaceThatTakesWindFixesNow(String leaderboardName, AsyncCallback<RegattaAndRaceIdentifier> callback);
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.sap.sailing.dashboards.gwt.client.actions;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sse.gwt.client.async.AsyncAction;
|
||||
|
||||
/**
|
||||
* @author Alexander Ries (D062114)
|
||||
*
|
||||
*/
|
||||
public class GetIDFromRaceThatTakesWindFixesNowAction implements AsyncAction<RegattaAndRaceIdentifier> {
|
||||
|
||||
private final RibDashboardServiceAsync ribDashboardService;
|
||||
private final String leaderboardName;
|
||||
|
||||
public GetIDFromRaceThatTakesWindFixesNowAction(RibDashboardServiceAsync ribDashboardService, String leaderboardName) {
|
||||
this.ribDashboardService = ribDashboardService;
|
||||
this.leaderboardName = leaderboardName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(AsyncCallback<RegattaAndRaceIdentifier> callback) {
|
||||
ribDashboardService.getIDFromRaceThatTakesWindFixesNow(leaderboardName, callback);
|
||||
}
|
||||
}
|
||||
+4
@@ -4,6 +4,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
@@ -37,6 +39,7 @@ public class RibDashboardDataRetriever implements TimeListener, RaceSelectionPro
|
||||
private final Object MUTEX;
|
||||
|
||||
private static final String PARAM_LEADERBOARD_NAME = "leaderboardName";
|
||||
private static final Logger logger = Logger.getLogger(RibDashboardDataRetriever.class.getName());
|
||||
|
||||
public RibDashboardDataRetriever(RibDashboardServiceAsync ribDashboardService) {
|
||||
initNonFinalMemberVariablesWithNoArgumentConstructor();
|
||||
@@ -74,6 +77,7 @@ public class RibDashboardDataRetriever implements TimeListener, RaceSelectionPro
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
logger.log(Level.INFO, caught.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+36
-19
@@ -5,50 +5,60 @@ import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
|
||||
import com.sap.sailing.dashboards.gwt.client.actions.GetIDFromRaceThatTakesWindFixesNowAction;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.gwt.ui.actions.GetWindInfoAction;
|
||||
import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.player.TimeListener;
|
||||
|
||||
public class WindBotDataRetriever implements TimeListener, RaceSelectionChangeListener, WindBotDataRetrieverProvider {
|
||||
public class WindBotDataRetriever implements TimeListener, WindBotDataRetrieverProvider {
|
||||
|
||||
private AsyncActionsExecutor asyncActionsExecutor;
|
||||
private final RibDashboardServiceAsync ribDashboardService;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private RegattaAndRaceIdentifier currentLiveRace;
|
||||
private List<NumberOfWindBotsChangeListener> numberOfWindBotsChangeListeners;
|
||||
private List<WindBotDataRetrieverListener> windBotDataRetrieverListeners;
|
||||
private List<String> windBotIDsInLiveRace;
|
||||
private String leaderboardName;
|
||||
|
||||
private final Set<String> windSourceTypeNames;
|
||||
private final int WIND_CHART_RESOLUTION_IN_MILLISECONDS = 5000;
|
||||
private final int ONE_HOUR_IN_MILLISECONDS = 1000*60*60;
|
||||
private final String LODA_WIND_CHART_DATA_CATEGORY = "loadWindChartData";
|
||||
private static final String PARAM_LEADERBOARD_NAME = "leaderboardName";
|
||||
private boolean didInitialLoading;
|
||||
|
||||
public WindBotDataRetriever(SailingServiceAsync sailingService) {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(WindBotDataRetriever.class.getName());
|
||||
|
||||
public WindBotDataRetriever(RibDashboardServiceAsync ribDashboardService, SailingServiceAsync sailingService) {
|
||||
this.ribDashboardService = ribDashboardService;
|
||||
this.sailingService = sailingService;
|
||||
currentLiveRace = null;
|
||||
didInitialLoading = false;
|
||||
asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
numberOfWindBotsChangeListeners = new ArrayList<NumberOfWindBotsChangeListener>();
|
||||
windBotDataRetrieverListeners = new ArrayList<WindBotDataRetrieverListener>();
|
||||
windBotIDsInLiveRace = new ArrayList<String>();
|
||||
windSourceTypeNames = new HashSet<>();
|
||||
this.leaderboardName = Window.Location.getParameter(PARAM_LEADERBOARD_NAME);
|
||||
windSourceTypeNames.add(WindSourceType.EXPEDITION.name());
|
||||
}
|
||||
|
||||
private void loadWindBotData(Date from, Date to, RegattaAndRaceIdentifier selectedRaceIdentifier) {
|
||||
if(!didInitialLoading){
|
||||
if (!didInitialLoading) {
|
||||
didInitialLoading = true;
|
||||
from = new Date(from.getTime()-ONE_HOUR_IN_MILLISECONDS);
|
||||
}
|
||||
logger.log(Level.INFO, "Executing WindInfoAction with from "+from+" and to "+to);
|
||||
GetWindInfoAction getWindInfoAction = new GetWindInfoAction(sailingService, selectedRaceIdentifier, from, to,
|
||||
WIND_CHART_RESOLUTION_IN_MILLISECONDS, windSourceTypeNames, /*
|
||||
* onlyUpToNewestEvent==true because we don't want to
|
||||
@@ -58,18 +68,22 @@ public class WindBotDataRetriever implements TimeListener, RaceSelectionChangeLi
|
||||
new AsyncCallback<WindInfoForRaceDTO>() {
|
||||
@Override
|
||||
public void onSuccess(WindInfoForRaceDTO result) {
|
||||
logger.log(Level.INFO, "Received Response from WindInfoAction");
|
||||
if (result != null) {
|
||||
if(windBotIDsInLiveRace.size() != getWindBotIdsFrom(result).size()){
|
||||
windBotIDsInLiveRace = getWindBotIdsFrom(result);
|
||||
notifyListenersAboutNumberOfWindBotChange(windBotIDsInLiveRace);
|
||||
logger.log(Level.INFO, "Number of Windbots changed");
|
||||
}
|
||||
notifyWindBotDataRetrieverListeners(result);
|
||||
} else {
|
||||
logger.log(Level.INFO, "Response WindInfoForRaceDTO from WindInfoAction null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
|
||||
logger.log(Level.INFO, caught.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -116,17 +130,20 @@ public class WindBotDataRetriever implements TimeListener, RaceSelectionChangeLi
|
||||
|
||||
@Override
|
||||
public void timeChanged(Date newTime, Date oldTime) {
|
||||
if (currentLiveRace != null) {
|
||||
loadWindBotData(oldTime, newTime, currentLiveRace);
|
||||
}
|
||||
}
|
||||
final Date finalNewTime = newTime;
|
||||
final Date finaloldTime = oldTime;
|
||||
GetIDFromRaceThatTakesWindFixesNowAction getIDFromRaceThatTakesWindFixesNowAction = new GetIDFromRaceThatTakesWindFixesNowAction(ribDashboardService, leaderboardName);
|
||||
asyncActionsExecutor.execute(getIDFromRaceThatTakesWindFixesNowAction, new AsyncCallback<RegattaAndRaceIdentifier>() {
|
||||
@Override
|
||||
public void onSuccess(RegattaAndRaceIdentifier result) {
|
||||
if(result != null)
|
||||
loadWindBotData(finaloldTime, finalNewTime, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RegattaAndRaceIdentifier> selectedRaces) {
|
||||
if (selectedRaces == null) {
|
||||
currentLiveRace = null;
|
||||
} else if (selectedRaces.size() > 0) {
|
||||
currentLiveRace = selectedRaces.get(0);
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
logger.log(Level.INFO, caught.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+18
-17
@@ -3,6 +3,7 @@ package com.sap.sailing.dashboards.gwt.client.notifications;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
@@ -21,38 +22,38 @@ public class BottomNotification extends FocusPanel {
|
||||
private Timer timer;
|
||||
private List<BottomNotificationClickListener> bottomNotificationClickListeners;
|
||||
|
||||
private static NotificationsResources resources = GWT.create(NotificationsResources.class);
|
||||
|
||||
public BottomNotification() {
|
||||
|
||||
this.addStyleName("bottomnotification");
|
||||
resources.notificationsStyle().ensureInjected();
|
||||
this.addStyleName(resources.notificationsStyle().bottomnotification());
|
||||
this.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
if (shown == true) {
|
||||
shown = false;
|
||||
BottomNotification.this.getElement().getStyle().setOpacity(1.0);
|
||||
nofitifyBottomNotificationClickListenersAboutClick();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.addStyleName("bottomnotification");
|
||||
bottomNotificationClickListeners = new ArrayList<BottomNotificationClickListener>();
|
||||
}
|
||||
|
||||
public void show(BottomNotificationType bottomNotificationType) {
|
||||
shown = true;
|
||||
this.removeStyleName("bottomnotificationhidden");
|
||||
this.addStyleName("bottomnotificationshow");
|
||||
this.getElement().setInnerHTML(bottomNotificationType.getMessage());
|
||||
this.getElement().getStyle().setBackgroundColor(bottomNotificationType.getBackgroundColorAsHex());
|
||||
this.getElement().getStyle().setColor(bottomNotificationType.getTextColorAsHex());
|
||||
if (bottomNotificationType.isShouldDisappearAfter20Seconds()) {
|
||||
if (shown == false) {
|
||||
this.removeStyleName(resources.notificationsStyle().bottomnotification_hidden());
|
||||
this.addStyleName(resources.notificationsStyle().bottomnotification_shown());
|
||||
this.getElement().setInnerHTML(bottomNotificationType.getMessage());
|
||||
this.getElement().getStyle().setBackgroundColor(bottomNotificationType.getBackgroundColorAsHex());
|
||||
this.getElement().getStyle().setColor(bottomNotificationType.getTextColorAsHex());
|
||||
Timer timer = new Timer() {
|
||||
public void run() {
|
||||
hide();
|
||||
}
|
||||
};
|
||||
timer.schedule(20000);
|
||||
timer.schedule(bottomNotificationType.timeToDisappearInMilliseconds());
|
||||
shown = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,10 +61,10 @@ public class BottomNotification extends FocusPanel {
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
}
|
||||
shown = false;
|
||||
this.removeStyleName("bottomnotificationshow");
|
||||
this.addStyleName("bottomnotificationhidden");
|
||||
this.removeStyleName(resources.notificationsStyle().bottomnotification_shown());
|
||||
this.addStyleName(resources.notificationsStyle().bottomnotification_hidden());
|
||||
this.getElement().setInnerHTML("");
|
||||
shown = false;
|
||||
}
|
||||
|
||||
public void addBottomNotificationClickListener(BottomNotificationClickListener bottomNotificationClickListener) {
|
||||
@@ -75,8 +76,8 @@ public class BottomNotification extends FocusPanel {
|
||||
}
|
||||
|
||||
private void nofitifyBottomNotificationClickListenersAboutClick() {
|
||||
for (BottomNotificationClickListener bncl : bottomNotificationClickListeners) {
|
||||
bncl.bottomNotificationClicked();
|
||||
for (BottomNotificationClickListener bottomNotificationClickListener : bottomNotificationClickListeners) {
|
||||
bottomNotificationClickListener.bottomNotificationClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -4,18 +4,18 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
|
||||
public enum BottomNotificationType {
|
||||
|
||||
NEW_STARTANALYSIS_AVAILABLE(StringMessages.INSTANCE.dashboardNewStartAnalysisAvailable(), "#F0AB00", "#000000", true);
|
||||
NEW_STARTANALYSIS_AVAILABLE(StringMessages.INSTANCE.dashboardNewStartAnalysisAvailable(), "#F0AB00", "#000000", 20000);
|
||||
|
||||
private String message;
|
||||
private String backgroundColorAsHex;
|
||||
private String textColorAsHex;
|
||||
private boolean shouldDisappearAfter20Seconds;
|
||||
private int timeToDisappearInMilliseconds;
|
||||
|
||||
private BottomNotificationType(String message, String backgroundColorAsHex, String textColorAsHex, boolean shouldDisappearAfter20Seconds) {
|
||||
private BottomNotificationType(String message, String backgroundColorAsHex, String textColorAsHex, int timeToDisappearInMilliseconds) {
|
||||
this.message = message;
|
||||
this.backgroundColorAsHex = backgroundColorAsHex;
|
||||
this.textColorAsHex = textColorAsHex;
|
||||
this.shouldDisappearAfter20Seconds = shouldDisappearAfter20Seconds;
|
||||
this.timeToDisappearInMilliseconds = timeToDisappearInMilliseconds;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
@@ -30,7 +30,7 @@ public enum BottomNotificationType {
|
||||
return textColorAsHex;
|
||||
}
|
||||
|
||||
public boolean isShouldDisappearAfter20Seconds() {
|
||||
return shouldDisappearAfter20Seconds;
|
||||
public int timeToDisappearInMilliseconds() {
|
||||
return timeToDisappearInMilliseconds;
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
@CHARSET "UTF-8";
|
||||
|
||||
.bottomnotification {
|
||||
position: absolute !important;
|
||||
opacity: 0.9;
|
||||
background-color: #F0AB00;
|
||||
height: 0pt;
|
||||
line-height: 0pt;
|
||||
width: 100%;
|
||||
bottom: 0pt;
|
||||
text-align: center;
|
||||
font-size: 15pt;
|
||||
line-height: 30pt;
|
||||
color: black;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.bottomnotification_shown {
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
|
||||
/* older webkit */
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
|
||||
/* custom */
|
||||
height: 30pt;
|
||||
line-height: 30pt;
|
||||
}
|
||||
|
||||
.bottomnotification_hidden {
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
|
||||
/* older webkit */
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
|
||||
/* custom */
|
||||
height: 0pt;
|
||||
line-height: 0pt;
|
||||
}
|
||||
|
||||
.wrongorientationnotification {
|
||||
position: absolute !important;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
background-color: white;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.wrongorientationnotification_shown {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-right: -100px;
|
||||
margin-top: -100px;
|
||||
border-radius: 100px;
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
|
||||
/* older webkit */
|
||||
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.wrongorientationnotification_hidden {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
marin-right: 0px;
|
||||
margin-top: 0px;
|
||||
border-radius: 0px;
|
||||
overflow: hidden;
|
||||
-webkit-transition: all 300ms;
|
||||
/* older webkit */
|
||||
-webkit-transition: all 300ms;
|
||||
-moz-transition: all 300ms;
|
||||
-o-transition: all 300ms;
|
||||
transition: all 300ms;
|
||||
opacity: 0.0;
|
||||
}
|
||||
|
||||
.wrongorientationnotification_logo {
|
||||
max-width: 40%;
|
||||
max-height: 40%;
|
||||
margin: 30%;
|
||||
margin-top: 23%
|
||||
}
|
||||
|
||||
.wrongorientationnotification_text {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
top: 76%;
|
||||
line-height: 10px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
color: grey;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.sap.sailing.dashboards.gwt.client.notifications;
|
||||
|
||||
import com.google.gwt.resources.client.ClientBundle;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
|
||||
/**
|
||||
* @author Alexander Ries (D062114)
|
||||
*
|
||||
*/
|
||||
public interface NotificationsResources extends ClientBundle {
|
||||
|
||||
@Source("Notifications.css")
|
||||
NotificationsStyle notificationsStyle();
|
||||
|
||||
public interface NotificationsStyle extends CssResource {
|
||||
public String bottomnotification();
|
||||
public String bottomnotification_shown();
|
||||
public String bottomnotification_hidden();
|
||||
public String wrongorientationnotification();
|
||||
public String wrongorientationnotification_shown();
|
||||
public String wrongorientationnotification_hidden();
|
||||
public String wrongorientationnotification_logo();
|
||||
public String wrongorientationnotification_text();
|
||||
}
|
||||
}
|
||||
+12
-8
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.dashboards.gwt.client.notifications;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.ui.AbsolutePanel;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
@@ -15,18 +16,21 @@ public class WrongDeviceOrientationNotification extends AbsolutePanel implements
|
||||
|
||||
private Label rotateDeviceLabel;
|
||||
|
||||
private static NotificationsResources resources = GWT.create(NotificationsResources.class);
|
||||
|
||||
public WrongDeviceOrientationNotification() {
|
||||
super();
|
||||
this.addStyleName("wrongOrientationNotification");
|
||||
this.addStyleName("wrongOrientationNotification_hidden");
|
||||
resources.notificationsStyle().ensureInjected();
|
||||
this.addStyleName(resources.notificationsStyle().wrongorientationnotification());
|
||||
this.addStyleName(resources.notificationsStyle().wrongorientationnotification_hidden());
|
||||
|
||||
Image rotateDeviceIcon = new Image();
|
||||
rotateDeviceIcon.setResource(RibDashboardImageResources.INSTANCE.rotatedevice());
|
||||
rotateDeviceIcon.getElement().addClassName("wrongOrientationNotification_logo");
|
||||
rotateDeviceIcon.getElement().addClassName(resources.notificationsStyle().wrongorientationnotification_logo());
|
||||
add(rotateDeviceIcon);
|
||||
|
||||
rotateDeviceLabel = new Label();
|
||||
rotateDeviceLabel.getElement().addClassName("wrongOrientationNotification_text");
|
||||
rotateDeviceLabel.getElement().addClassName(resources.notificationsStyle().wrongorientationnotification_text());
|
||||
rotateDeviceLabel.setText("Rotate Device");
|
||||
add(rotateDeviceLabel);
|
||||
|
||||
@@ -35,14 +39,14 @@ public class WrongDeviceOrientationNotification extends AbsolutePanel implements
|
||||
}
|
||||
|
||||
public void show() {
|
||||
this.removeStyleName("wrongOrientationNotification_hidden");
|
||||
this.addStyleName("wrongOrientationNotification_shown");
|
||||
this.removeStyleName(resources.notificationsStyle().wrongorientationnotification_hidden());
|
||||
this.addStyleName(resources.notificationsStyle().wrongorientationnotification_shown());
|
||||
BlurEffect.getInstance().addToView(RootLayoutPanel.get());
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
this.removeStyleName("wrongOrientationNotification_shown");
|
||||
this.addStyleName("wrongOrientationNotification_hidden");
|
||||
this.removeStyleName(resources.notificationsStyle().wrongorientationnotification_shown());
|
||||
this.addStyleName(resources.notificationsStyle().wrongorientationnotification_hidden());
|
||||
BlurEffect.getInstance().removeFromView(RootLayoutPanel.get());
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -271,7 +271,7 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
|
||||
if (displaysCards == true) {
|
||||
if (clickedLeft) {
|
||||
if (page != 0) {
|
||||
currentScrollPosition = currentScrollPosition + SCROLL_OFFSET_STARTANALYSIS_CARDS;
|
||||
currentScrollPosition += SCROLL_OFFSET_STARTANALYSIS_CARDS;
|
||||
page--;
|
||||
startanalysis_card_container.getElement().getStyle().setLeft(currentScrollPosition, Unit.PCT);
|
||||
notifyStartAnalysisPageChangeListener(page);
|
||||
|
||||
+6
-4
@@ -72,10 +72,12 @@ public class StartlineAdvantagesByWindComponent extends Composite implements Has
|
||||
|
||||
@Override
|
||||
public void onSuccess(StartlineAdvantagesWithMaxAndAverageDTO result) {
|
||||
startlineAdvantagesOnLineChart.setStartlineAdvantages(result.advantages);
|
||||
advantageMaximumLiveAverage.setLiveValue(""+result.maximum);
|
||||
advantageMaximumLiveAverage.setAverageValue(""+result.average);
|
||||
}
|
||||
if (result != null) {
|
||||
startlineAdvantagesOnLineChart.setStartlineAdvantages(result.advantages);
|
||||
advantageMaximumLiveAverage.setLiveValue("" + result.maximum);
|
||||
advantageMaximumLiveAverage.setAverageValue("" + result.average);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
+2
-23
@@ -2,8 +2,6 @@ package com.sap.sailing.dashboards.gwt.client.startlineadvantage;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.moxieapps.gwt.highcharts.client.Animation;
|
||||
import org.moxieapps.gwt.highcharts.client.Animation.Easing;
|
||||
@@ -67,7 +65,6 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
|
||||
private Series series;
|
||||
|
||||
private static final int POINT_ADDING_ANIMATION_DURATION_IN_MILLIS = 2000;
|
||||
private static final Logger logger = Logger.getLogger(StartlineAdvantagesOnLineChart.class.getName());
|
||||
|
||||
public StartlineAdvantagesOnLineChart() {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
@@ -200,9 +197,6 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
|
||||
}
|
||||
|
||||
public void setStartlineAdvantages(List<StartLineAdvantageDTO> startlineAdvantages) {
|
||||
for(StartLineAdvantageDTO startLineAdvantageDTO : startlineAdvantages) {
|
||||
logger.log(Level.INFO, startLineAdvantageDTO.distanceToRCBoatInMeters +" "+startLineAdvantageDTO.startLineAdvantage);
|
||||
}
|
||||
if (series.getPoints() != null && series.getPoints().length > 0) {
|
||||
updateStartlineAdvantages(startlineAdvantages, series);
|
||||
} else {
|
||||
@@ -213,19 +207,8 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
|
||||
}
|
||||
|
||||
private void updateStartlineAdvantages(List<StartLineAdvantageDTO> startlineAdvantages, Series series) {
|
||||
// Series newSeries = createSeries(chart);
|
||||
// addStartlineAdvantages(startlineAdvantages, newSeries);
|
||||
removeAllSeriesPoints(chart.getSeries()[0]);
|
||||
logger.log(Level.INFO, "SERIES: " + chart.getSeries().length);
|
||||
addStartlineAdvantages(startlineAdvantages, series);
|
||||
// int counter = 0;
|
||||
// for (Point point : series.getPoints()) {
|
||||
// if(startlineAdvantages.size() -1 > counter){
|
||||
// StartLineAdvantageDTO currentNewStartlineAdvantage = startlineAdvantages.get(counter);
|
||||
// series.addPoint(currentNewStartlineAdvantage.distanceToRCBoatInMeters, currentNewStartlineAdvantage.startLineAdvantage);
|
||||
// counter++;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private void removeAllSeriesPoints(Series series) {
|
||||
@@ -235,11 +218,10 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
|
||||
}
|
||||
|
||||
private void addStartlineAdvantages(List<StartLineAdvantageDTO> startlineAdvantages, Series series){
|
||||
//TODO Build this with forEach Consumer as soon as the bundle uses GWT 2.8 with Java 8 Support.
|
||||
//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, false, false, false);
|
||||
//new Animation().setDuration(POINT_ADDING_ANIMATION_DURATION_IN_MILLIS)
|
||||
}
|
||||
setConfidenceGradientColorToSeries(series, startlineAdvantages);
|
||||
chart.redraw();
|
||||
@@ -287,10 +269,7 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
|
||||
lastConfidence = startlineAdvantageDTO.confidence;
|
||||
double gradientPosition = getGradientStopPositionFromStartlineLenghtAndDistanceToRCBoat(lineLenght,
|
||||
startlineAdvantageDTO.distanceToRCBoatInMeters);
|
||||
logger.log(Level.INFO, "Confidence " + startlineAdvantageDTO.confidence + "gradientPosition"
|
||||
+ gradientPosition);
|
||||
color.addColorStop(gradientPosition,
|
||||
getColorAsHexStringFromConfidence(startlineAdvantageDTO.confidence));
|
||||
color.addColorStop(gradientPosition, getColorAsHexStringFromConfidence(startlineAdvantageDTO.confidence));
|
||||
}
|
||||
}
|
||||
return color;
|
||||
|
||||
+6
@@ -3,6 +3,8 @@ package com.sap.sailing.dashboards.gwt.client.windchart;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.moxieapps.gwt.highcharts.client.Axis.Type;
|
||||
import org.moxieapps.gwt.highcharts.client.Chart;
|
||||
@@ -71,6 +73,8 @@ public class VerticalWindChart extends Composite implements HasWidgets {
|
||||
private static final int MAX_SERIES_POINTS = 100000000;
|
||||
|
||||
private static VerticalWindChartUiBinder uiBinder = GWT.create(VerticalWindChartUiBinder.class);
|
||||
|
||||
private static final Logger logger = Logger.getLogger(VerticalWindChart.class.getName());
|
||||
|
||||
interface VerticalWindChartUiBinder extends UiBinder<Widget, VerticalWindChart> {
|
||||
}
|
||||
@@ -194,9 +198,11 @@ public class VerticalWindChart extends Composite implements HasWidgets {
|
||||
if (verticalWindChartSeries == null) {
|
||||
initVerticalWindChartSeries();
|
||||
verticalWindChartSeries.setPoints(points, true);
|
||||
logger.log(Level.INFO, "Set Points");
|
||||
} else {
|
||||
for (Point point : points) {
|
||||
verticalWindChartSeries.addPoint(point, true, false, false);
|
||||
logger.log(Level.INFO, "Add Point");
|
||||
}
|
||||
}
|
||||
verticalWindChartSeries.updateThreshold("" + average);
|
||||
|
||||
+35
-21
@@ -6,6 +6,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
@@ -31,6 +32,7 @@ import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
@@ -38,7 +40,6 @@ import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
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.Pair;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
@@ -89,7 +90,7 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib
|
||||
}
|
||||
|
||||
protected RacingEventService getRacingEventService() {
|
||||
return racingEventServiceTracker.getService(); // grab the service
|
||||
return racingEventServiceTracker.getService();
|
||||
}
|
||||
|
||||
private PolarDataService getPolarService() {
|
||||
@@ -129,6 +130,22 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib
|
||||
}
|
||||
return lRInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaAndRaceIdentifier getIDFromRaceThatTakesWindFixesNow(String leaderboardName) {
|
||||
RegattaAndRaceIdentifier result = null;
|
||||
if(leaderboardName != null) {
|
||||
List<TrackedRace> trackedRaces = getTrackedRacesFromLeaderboard(leaderboardName);
|
||||
List<TrackedRace> filteredTrackedRaces = trackedRaces.stream().filter(trackedRace -> trackedRace.takesWindFixWithTimePoint(MillisecondsTimePoint.now())).collect(Collectors.toList());
|
||||
if(filteredTrackedRaces != null && filteredTrackedRaces.size() > 0) {
|
||||
TrackedRace raceThatTakesWindNow = filteredTrackedRaces.get(0);
|
||||
if(raceThatTakesWindNow != null) {
|
||||
result = raceThatTakesWindNow.getRaceIdentifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void fillLiveRaceInfoDTOWithRaceData(RibDashboardRaceInfoDTO lRInfo, TimePoint now) {
|
||||
if (runningRace != null) {
|
||||
@@ -164,16 +181,9 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib
|
||||
for (RaceColumn column : lb.getRaceColumns()) {
|
||||
for (Fleet fleet : column.getFleets()) {
|
||||
TrackedRace race = column.getTrackedRace(fleet);
|
||||
if (race != null) {
|
||||
if (race != null && race.isLive(MillisecondsTimePoint.now())) {
|
||||
result = race;
|
||||
notifyLiveTrackedRaceListenerAboutLiveTrackedRaceChange(race);
|
||||
TimePoint startOfRace = race.getStartOfRace();
|
||||
// not relying on isLive() because the time window is too short
|
||||
// to retrieve wind information we need to extend the time window
|
||||
if (startOfRace != null && race.getEndOfRace() == null &&
|
||||
MillisecondsTimePoint.now().after(startOfRace.minus(Duration.ONE_MINUTE.times(20)))) {
|
||||
result = race;
|
||||
// no break here as we want to have the last race that is deemed to be live
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,19 +278,23 @@ public class RibDashboardServiceImpl extends RemoteServiceServlet implements Rib
|
||||
@Override
|
||||
public List<StartAnalysisDTO> getStartAnalysisListForCompetitorIDAndLeaderboardName(String competitorIdAsString,
|
||||
String leaderboardName) {
|
||||
List<StartAnalysisDTO> startAnalysisDTOs = new ArrayList<StartAnalysisDTO>();
|
||||
if (leaderboardName != null) {
|
||||
Competitor competitor = baseDomainFactory.getCompetitorStore().getExistingCompetitorByIdAsString(competitorIdAsString);
|
||||
List<TrackedRace> trackedRacesForLeaderBoardName = getTrackedRacesFromLeaderboard(leaderboardName);
|
||||
for (TrackedRace trackedRace : trackedRacesForLeaderBoardName) {
|
||||
StartAnalysisDTO startAnalysisDTO = startAnalysisCreationController
|
||||
.checkStartAnalysisForCompetitorInTrackedRace(competitor, trackedRace);
|
||||
if (startAnalysisDTO != null) {
|
||||
startAnalysisDTOs.add(startAnalysisDTO);
|
||||
List<StartAnalysisDTO> result = null;
|
||||
if (competitorIdAsString != null && leaderboardName != null) {
|
||||
result = new ArrayList<StartAnalysisDTO>();
|
||||
try {
|
||||
Competitor competitor = baseDomainFactory.getCompetitorStore().getExistingCompetitorByIdAsString(competitorIdAsString);
|
||||
List<TrackedRace> trackedRacesForLeaderBoardName = getTrackedRacesFromLeaderboard(leaderboardName);
|
||||
for (TrackedRace trackedRace : trackedRacesForLeaderBoardName) {
|
||||
StartAnalysisDTO startAnalysisDTO = startAnalysisCreationController.checkStartAnalysisForCompetitorInTrackedRace(competitor, trackedRace);
|
||||
if (startAnalysisDTO != null) {
|
||||
result.add(startAnalysisDTO);
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
logger.log(Level.INFO, "", e);
|
||||
}
|
||||
}
|
||||
return startAnalysisDTOs;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -10,8 +10,8 @@ import com.sap.sse.common.TimePoint;
|
||||
|
||||
public abstract class AbstractStartAnalysisCreationValidator {
|
||||
|
||||
private static int MINIMUM_MARKPASSIINGS_AT_FIRST_MARK = 3;
|
||||
private static long MINIMUM_RACE_PROGRESSION_IN_MILLISECONDS = 6*60*1000;
|
||||
protected static int MINIMUM_MARKPASSIINGS_AT_FIRST_MARK = 3;
|
||||
protected static long MINIMUM_RACE_PROGRESSION_IN_MILLISECONDS = 6*60*1000;
|
||||
|
||||
protected boolean threeCompetitorsPassedSecondWayPoint(TrackedRace trackedRace){
|
||||
Waypoint secondWaypoint = trackedRace.getRace().getCourse().getFirstLeg().getTo();
|
||||
@@ -45,7 +45,8 @@ public abstract class AbstractStartAnalysisCreationValidator {
|
||||
}
|
||||
|
||||
protected boolean raceProgressedFarEnough(Competitor competitor, TrackedRace trackedRace){
|
||||
if(trackedRace.isGateStart()){
|
||||
final Boolean isGateStart = trackedRace.isGateStart();
|
||||
if(isGateStart == Boolean.TRUE){
|
||||
return gateStartGolfFlagIsDown(trackedRace);
|
||||
}else{
|
||||
return competitorPassedSecondWayPoint(competitor, trackedRace);
|
||||
|
||||
+7
-6
@@ -19,15 +19,16 @@ public class StartAnalysisCreationController extends AbstractStartAnalysisCreati
|
||||
}
|
||||
|
||||
public StartAnalysisDTO checkStartAnalysisForCompetitorInTrackedRace(Competitor competitor, TrackedRace trackedRace) {
|
||||
StartAnalysisDTO startAnalysisDTO;
|
||||
StartAnalysisDTO result = null;
|
||||
if (threeCompetitorsPassedSecondWayPoint(trackedRace) &&
|
||||
raceProgressedFarEnough(competitor, trackedRace))
|
||||
{
|
||||
logger.log(Level.INFO, "Trigger StartAnalysisDTO creation");
|
||||
startAnalysisDTO = startAnalysisDTOFactory.createStartAnalysisForCompetitorAndTrackedRace(competitor, trackedRace);
|
||||
return startAnalysisDTO;
|
||||
}else{
|
||||
return null;
|
||||
logger.log(Level.INFO, "Creating startanalysis for race "+trackedRace.getRace().getName()+" and competitor: " + competitor.getName());
|
||||
result = startAnalysisDTOFactory.createStartAnalysisForCompetitorAndTrackedRace(competitor, trackedRace);
|
||||
|
||||
}else {
|
||||
logger.log(Level.INFO, "Waiting to create startanalysis for race "+trackedRace.getRace().getName()+" and competitor: " + competitor.getName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+14
-20
@@ -32,7 +32,6 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
|
||||
|
||||
private final com.sap.sailing.domain.base.DomainFactory baseDomainFactory;
|
||||
|
||||
private static int MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS = 3;
|
||||
private static int DEFAULT_GATE_START_INTERVALL_IN_MILLISECONDS = 5*60*1000;
|
||||
private static int ONE_MINUTE_INTERVALL_IN_MILLISECONDS = 60*1000;
|
||||
|
||||
@@ -42,17 +41,14 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
|
||||
baseDomainFactory = racingEventService.getBaseDomainFactory();
|
||||
}
|
||||
|
||||
public StartAnalysisDTO createStartAnalysisForCompetitorAndTrackedRace(Competitor competitor,
|
||||
TrackedRace trackedRace) {
|
||||
public StartAnalysisDTO createStartAnalysisForCompetitorAndTrackedRace(Competitor competitor, TrackedRace trackedRace) {
|
||||
StartAnalysisDTO startAnalysisDTO = new StartAnalysisDTO();
|
||||
addStaticDataToStartAnalysisDTOFrom(startAnalysisDTO, trackedRace);
|
||||
List<StartAnalysisCompetitorDTO> competitors = new ArrayList<StartAnalysisCompetitorDTO>();
|
||||
Waypoint secondWaypoint = trackedRace.getRace().getCourse().getFirstLeg().getTo();
|
||||
List<MarkPassing> markPassingsInOrder = convertMarkpPassingsIteratorToList(trackedRace.getMarkPassingsInOrder(
|
||||
secondWaypoint).iterator());
|
||||
|
||||
List<MarkPassing> markPassingsInOrder = convertMarkpPassingsIteratorToList(trackedRace.getMarkPassingsInOrder(secondWaypoint).iterator());
|
||||
boolean isCompetitorOneOfFirstThree = false;
|
||||
for (int i = 0; i < MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS; i++) {
|
||||
for (int i = 0; i < MINIMUM_MARKPASSIINGS_AT_FIRST_MARK; i++) {
|
||||
competitors.add(createStartAnalysisCompetitorDTO(trackedRace, i + 1, markPassingsInOrder.get(i).getCompetitor()));
|
||||
if (markPassingsInOrder.get(i).getCompetitor().equals(competitor)) {
|
||||
isCompetitorOneOfFirstThree = true;
|
||||
@@ -60,17 +56,14 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
|
||||
}
|
||||
|
||||
if (!isCompetitorOneOfFirstThree) {
|
||||
int rankOfCompetitorWhilePassingSecondWaypoint = getRankOfCompetitorWhilePassingSecondWaypoint(competitor,
|
||||
trackedRace);
|
||||
competitors.add(createStartAnalysisCompetitorDTO(trackedRace, rankOfCompetitorWhilePassingSecondWaypoint,
|
||||
competitor));
|
||||
int rankOfCompetitorWhilePassingSecondWaypoint = getRankOfCompetitorWhilePassingSecondWaypoint(competitor, trackedRace);
|
||||
competitors.add(createStartAnalysisCompetitorDTO(trackedRace, rankOfCompetitorWhilePassingSecondWaypoint, competitor));
|
||||
}
|
||||
|
||||
startAnalysisDTO.competitor = baseDomainFactory.getCompetitorStore().convertToCompetitorDTO(competitor);
|
||||
startAnalysisDTO.startAnalysisCompetitorDTOs = competitors;
|
||||
|
||||
if (trackedRace.isGateStart()) {
|
||||
logger.log(Level.INFO, "IS GATESTART");
|
||||
final Boolean isGateStart = trackedRace.isGateStart();
|
||||
if(isGateStart == Boolean.TRUE){
|
||||
logger.log(Level.INFO, "Creating startanalysis for gate start");
|
||||
startAnalysisDTO.racingProcedureType = RacingProcedureType.GateStart;
|
||||
long timePointOfGolfDownTime = trackedRace.getGateStartGolfDownTime();
|
||||
startAnalysisDTO.timeOfStartInMilliSeconds = trackedRace.getStartOfRace().asMillis();
|
||||
@@ -80,12 +73,13 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
|
||||
startAnalysisDTO.tailLenghtInMilliseconds = timePointOfGolfDownTime-trackedRace.getStartOfRace().asMillis();
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.INFO, "Creating startanalysis for ess start");
|
||||
startAnalysisDTO.racingProcedureType = RacingProcedureType.ESS;
|
||||
startAnalysisDTO.timeOfStartInMilliSeconds = trackedRace.getStartOfRace().asMillis();
|
||||
startAnalysisDTO.tailLenghtInMilliseconds = ONE_MINUTE_INTERVALL_IN_MILLISECONDS;
|
||||
}
|
||||
startAnalysisDTO.regattaAndRaceIdentifier = trackedRace.getRaceIdentifier();
|
||||
logger.log(Level.INFO, "Created StartAnalysis For Competitor " + competitor.getName() + " and "+ trackedRace.getRace().getName());
|
||||
logger.log(Level.INFO, "Created startanalysis for competitor " + competitor.getName() + " and "+ trackedRace.getRace().getName());
|
||||
return startAnalysisDTO;
|
||||
}
|
||||
|
||||
@@ -109,8 +103,7 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
|
||||
return 0;
|
||||
}
|
||||
|
||||
private StartAnalysisDTO addStaticDataToStartAnalysisDTOFrom(StartAnalysisDTO startAnalysisDTO,
|
||||
TrackedRace trackedRace) {
|
||||
private StartAnalysisDTO addStaticDataToStartAnalysisDTOFrom(StartAnalysisDTO startAnalysisDTO, TrackedRace trackedRace) {
|
||||
startAnalysisDTO.raceName = trackedRace.getRace().getName();
|
||||
startAnalysisDTO.startAnalysisWindLineInfoDTO = createStartAnalysisWindAndLineData(trackedRace);
|
||||
return startAnalysisDTO;
|
||||
@@ -129,7 +122,8 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
|
||||
tableentry.rankAtFirstMark = rank;
|
||||
tableentry.teamName = competitor.getName();
|
||||
tableentry.speedAtStartTime = trackedRace.getSpeed(competitor, 1).getKnots();
|
||||
if (trackedRace.isGateStart()) {
|
||||
final Boolean isGateStart = trackedRace.isGateStart();
|
||||
if(isGateStart == Boolean.TRUE){
|
||||
tableentry.distanceToLineAtStartTime = trackedRace.getDistanceFromStarboardSideOfStartLineWhenPassingStart(
|
||||
competitor).getMeters();
|
||||
} else {
|
||||
@@ -177,7 +171,7 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
|
||||
return StartlineAdvantageType.WIND;
|
||||
}
|
||||
} catch (NoWindException e) {
|
||||
e.printStackTrace();
|
||||
logger.log(Level.INFO, "", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-33
@@ -51,42 +51,45 @@ public class StartlineAdvantagesCalculator extends AbstracPreCalculationDataRet
|
||||
// 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
|
||||
public StartlineAdvantagesWithMaxAndAverageDTO getStartLineAdvantagesAccrossLineAtTimePoint(TimePoint timepoint){
|
||||
public StartlineAdvantagesWithMaxAndAverageDTO getStartLineAdvantagesAccrossLineAtTimePoint(TimePoint timepoint) {
|
||||
StartlineAdvantagesWithMaxAndAverageDTO result = new StartlineAdvantagesWithMaxAndAverageDTO();
|
||||
if (currentLiveTrackedRace != null) {
|
||||
retrieveDataForCalculation(currentLiveTrackedRace);
|
||||
if(isStartlineCompletelyUnderneathLaylines()) {
|
||||
logger.log(Level.INFO, "Startline is completely underneath laylines");
|
||||
Pair<Double, Double> advantagesRange = new Pair<Double, Double>(0.0, startlineLenghtInMeters);
|
||||
result.advantages = calculateStartlineAdvantagesUnderneathLaylinesInRange(advantagesRange);
|
||||
double maximum = getMaximumAdvantageOfStartlineAdvantageDTOs(result.advantages);
|
||||
result.maximum = maximum;
|
||||
advantageMaximumAverage.add(maximum);
|
||||
result.average = advantageMaximumAverage.getAverage();
|
||||
} else if (isStartlineCompletelyAboveLaylines()) {
|
||||
logger.log(Level.INFO, "Startline is completely above laylines");
|
||||
Pair<Double, Double> advantagesRange = new Pair<Double, Double>(0.0, startlineLenghtInMeters);
|
||||
result.advantages = calculatePolarBasedStartlineAdvantagesInRange(advantagesRange);
|
||||
subtractMinimumOfAllStartlineAdvantages(result.advantages);
|
||||
double maximum = getMaximumAdvantageOfStartlineAdvantageDTOs(result.advantages);
|
||||
result.maximum = maximum;
|
||||
advantageMaximumAverage.add(maximum);
|
||||
result.average = advantageMaximumAverage.getAverage();
|
||||
subtractAgainstMaximumOfAllStartlineAdvantages(result.advantages, maximum);
|
||||
} else {
|
||||
logger.log(Level.INFO, "Layline(s) cross startline");
|
||||
Position intersectionOfRightLaylineAndStartline = getIntersectionOfRightLaylineAndStartline();
|
||||
Position intersectionOfleftLaylineAndStartline = getIntersectionOfLeftLaylineAndStartline();
|
||||
Pair<Double, Double> polarBasedStartlineAdvatagesRange = getStartAndEndPointOfPolarBasedStartlineAdvatagesInDistancesToRCBoat(intersectionOfRightLaylineAndStartline, intersectionOfleftLaylineAndStartline);
|
||||
Pair<Double, Double> pinEndStartlineAdvatagesRange = getPinEndStartlineAdvantagesRangeFromPolarAdvantagesRange(polarBasedStartlineAdvatagesRange);
|
||||
result.advantages = calculatePolarBasedStartlineAdvantagesInRange(polarBasedStartlineAdvatagesRange);
|
||||
subtractMinimumOfAllStartlineAdvantages(result.advantages);
|
||||
double maximum = getMaximumAdvantageOfStartlineAdvantageDTOs(result.advantages);
|
||||
result.maximum = maximum;
|
||||
advantageMaximumAverage.add(maximum);
|
||||
result.average = advantageMaximumAverage.getAverage();
|
||||
subtractAgainstMaximumOfAllStartlineAdvantages(result.advantages, maximum);
|
||||
addClosingZeroPointToMixedAdvantages(result.advantages, pinEndStartlineAdvatagesRange);
|
||||
if (wind != null) {
|
||||
if (isStartlineCompletelyUnderneathLaylines()) {
|
||||
logger.log(Level.INFO, "Startline is completely underneath laylines");
|
||||
Pair<Double, Double> advantagesRange = new Pair<Double, Double>(0.0, startlineLenghtInMeters);
|
||||
result.advantages = calculateStartlineAdvantagesUnderneathLaylinesInRange(advantagesRange);
|
||||
double maximum = getMaximumAdvantageOfStartlineAdvantageDTOs(result.advantages);
|
||||
result.maximum = maximum;
|
||||
advantageMaximumAverage.add(maximum);
|
||||
result.average = advantageMaximumAverage.getAverage();
|
||||
} else if (isStartlineCompletelyAboveLaylines()) {
|
||||
logger.log(Level.INFO, "Startline is completely above laylines");
|
||||
Pair<Double, Double> advantagesRange = new Pair<Double, Double>(0.0, startlineLenghtInMeters);
|
||||
result.advantages = calculatePolarBasedStartlineAdvantagesInRange(advantagesRange);
|
||||
subtractMinimumOfAllStartlineAdvantages(result.advantages);
|
||||
double maximum = getMaximumAdvantageOfStartlineAdvantageDTOs(result.advantages);
|
||||
result.maximum = maximum;
|
||||
advantageMaximumAverage.add(maximum);
|
||||
result.average = advantageMaximumAverage.getAverage();
|
||||
subtractAgainstMaximumOfAllStartlineAdvantages(result.advantages, maximum);
|
||||
} else {
|
||||
logger.log(Level.INFO, "Layline(s) cross startline");
|
||||
Position intersectionOfRightLaylineAndStartline = getIntersectionOfRightLaylineAndStartline();
|
||||
Position intersectionOfleftLaylineAndStartline = getIntersectionOfLeftLaylineAndStartline();
|
||||
Pair<Double, Double> polarBasedStartlineAdvatagesRange = getStartAndEndPointOfPolarBasedStartlineAdvatagesInDistancesToRCBoat(
|
||||
intersectionOfRightLaylineAndStartline, intersectionOfleftLaylineAndStartline);
|
||||
Pair<Double, Double> pinEndStartlineAdvatagesRange = getPinEndStartlineAdvantagesRangeFromPolarAdvantagesRange(polarBasedStartlineAdvatagesRange);
|
||||
result.advantages = calculatePolarBasedStartlineAdvantagesInRange(polarBasedStartlineAdvatagesRange);
|
||||
subtractMinimumOfAllStartlineAdvantages(result.advantages);
|
||||
double maximum = getMaximumAdvantageOfStartlineAdvantageDTOs(result.advantages);
|
||||
result.maximum = maximum;
|
||||
advantageMaximumAverage.add(maximum);
|
||||
result.average = advantageMaximumAverage.getAverage();
|
||||
subtractAgainstMaximumOfAllStartlineAdvantages(result.advantages, maximum);
|
||||
addClosingZeroPointToMixedAdvantages(result.advantages, pinEndStartlineAdvatagesRange);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.INFO, "No live race available for startlineadvantages calculation");
|
||||
|
||||
-19
@@ -1,9 +1,5 @@
|
||||
package com.sap.sailing.dashboards.gwt.server.startlineadvantages.precalculation;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.dashboards.gwt.server.startlineadvantages.StartlineAdvantagesCalculator;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
@@ -24,26 +20,11 @@ public abstract class AbstracPreCalculationDataRetriever implements PreCalculati
|
||||
public Wind wind;
|
||||
public double meouvreAngle;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(StartlineAdvantagesCalculator.class.getName());
|
||||
|
||||
protected void retrieveDataForCalculation(TrackedRace trackedRace) {
|
||||
startlineAndFirstMarkPositions = retrieveMarkPositions(trackedRace);
|
||||
startlineAdvantageAtPinEndInMeters = retrieveStartlineAdvantage(trackedRace);
|
||||
startlineLenghtInMeters = retrieveStartlineLenght(trackedRace);
|
||||
wind = retrieveWindAtPosition(startlineAndFirstMarkPositions.startBoatPosition, trackedRace);
|
||||
meouvreAngle = retrieveManouvreAngleAtWindSpeedAndBoatClass(new BoatClassImpl("Extreme40", BoatClassMasterdata.EXTREME_40), ManeuverType.TACK, wind);
|
||||
printData();
|
||||
}
|
||||
|
||||
private void printData() {
|
||||
logger.log(Level.INFO, "Retrieved pre calculation data for startline advantages calculation");
|
||||
logger.log(Level.INFO, "startlineAndFirstMarkPositions.startBoatPosition "+startlineAndFirstMarkPositions.startBoatPosition);
|
||||
logger.log(Level.INFO, "startlineAndFirstMarkPositions.pinEndPosition "+startlineAndFirstMarkPositions.pinEndPosition);
|
||||
logger.log(Level.INFO, "startlineAndFirstMarkPositions.firstMarkPosition "+startlineAndFirstMarkPositions.firstMarkPosition);
|
||||
logger.log(Level.INFO, "startlineAdvantageAtPinEndInMeters "+startlineAdvantageAtPinEndInMeters);
|
||||
logger.log(Level.INFO, "startlineLenghtInMeters "+startlineLenghtInMeters);
|
||||
logger.log(Level.INFO, "wind.getBeaufort() "+wind.getKnots());
|
||||
logger.log(Level.INFO, "wind.getBearing().getDegrees() "+wind.getBearing().getDegrees());
|
||||
logger.log(Level.INFO, "meouvreAngle.getDegrees() "+meouvreAngle);
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -14,14 +14,16 @@ import com.sap.sailing.domain.polars.PolarDataService;
|
||||
*/
|
||||
public interface PreCalculationPolarDataRetriever {
|
||||
|
||||
default double retrieveManouvreAngleAtWindSpeedAndBoatClass(BoatClass boatClass, ManeuverType maneuverType,
|
||||
Speed windSpeed) {
|
||||
default double retrieveManouvreAngleAtWindSpeedAndBoatClass(BoatClass boatClass, ManeuverType maneuverType, Speed windSpeed) {
|
||||
double result = 0;
|
||||
try {
|
||||
BearingWithConfidence<Void> bearingWithConfidence = getPolarDataService().getManeuverAngle(boatClass, maneuverType, windSpeed);
|
||||
result = bearingWithConfidence.getObject().getDegrees();
|
||||
if (boatClass != null && maneuverType != null && windSpeed != null) {
|
||||
BearingWithConfidence<Void> bearingWithConfidence = getPolarDataService().getManeuverAngle(boatClass, maneuverType, windSpeed);
|
||||
result = bearingWithConfidence.getObject().getDegrees();
|
||||
} else {
|
||||
result = DefaultPolarValues.getManouvreAngle(ManeuverType.TACK);
|
||||
}
|
||||
} catch (NotEnoughDataHasBeenAddedException | NullPointerException e) {
|
||||
result = DefaultPolarValues.getManouvreAngle(ManeuverType.TACK);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
|
||||
+1
@@ -48,6 +48,7 @@
|
||||
|
||||
<set-property name="gwt.logging.enabled" value="TRUE" />
|
||||
<set-property name="gwt.logging.logLevel" value="FINE" />
|
||||
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
|
||||
|
||||
<set-property name="user.agent" value="safari" />
|
||||
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ Bft12=Orkan
|
||||
RelativeScoreInRace=Relative Wertung im Rennen (0 am besten; 1 am schlechtesten)
|
||||
WindSpeedInBeaufort=Windgeschwindigkeit in Bft.
|
||||
DistanceAtStart=Distanz zur Startlinie zum Startzeitpunkt
|
||||
SpeedAtStart=Geschwindigkeit zum Startzeitpunkt
|
||||
SpeedWhenStarting=Geschwindigkeit beim Überqueren der Startlinie
|
||||
SpeedTenSecondsBeforeStart=Geschwindigkeit 10s vor dem Startzeitpunkt
|
||||
RankAtFirstMark=Position beim ersten Wegpunkt
|
||||
NumberOfTacks=Anzahl der Wenden
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ Bft12=Hurricane
|
||||
RelativeScoreInRace=Relative score in race (0 best; 1 worst)
|
||||
WindSpeedInBeaufort=Wind speed in Bft
|
||||
DistanceAtStart=Distance to start at start
|
||||
SpeedAtStart=Speed at start
|
||||
SpeedWhenStarting=Speed when starting
|
||||
SpeedTenSecondsBeforeStart=Speed 10s before start
|
||||
RankAtFirstMark=Rank at First Mark
|
||||
NumberOfTacks=Number of Tacks
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@ public interface HasRaceOfCompetitorContext {
|
||||
@Statistic(messageKey="DistanceToStarboardSideAtStart", resultDecimals=2, ordinal=1)
|
||||
public Double getNormalizedDistanceToStarboardSideAtStart();
|
||||
|
||||
@Connector(messageKey="SpeedAtStart", ordinal=2)
|
||||
public Speed getSpeedAtStart();
|
||||
@Connector(messageKey="SpeedWhenStarting", ordinal=2)
|
||||
public Speed getSpeedWhenStarting();
|
||||
|
||||
@Connector(messageKey="SpeedTenSecondsBeforeStart", ordinal=3)
|
||||
public Speed getSpeedTenSecondsBeforeStart();
|
||||
|
||||
+2
-2
@@ -28,8 +28,8 @@ public class ParallelDistanceMaxAggregationProcessor extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Distance compareValuesAndReturnNewValue(Distance previousValue, Distance newValue) {
|
||||
return previousValue.getMeters() >= newValue.getMeters() ? previousValue : newValue;
|
||||
protected Distance compareValuesAndReturnNewResult(Distance currentResult, Distance newValue) {
|
||||
return currentResult.getMeters() >= newValue.getMeters() ? currentResult : newValue;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -28,8 +28,8 @@ public class ParallelDistanceMinAggregationProcessor extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Distance compareValuesAndReturnNewValue(Distance previousValue, Distance newValue) {
|
||||
return previousValue.getMeters() <= newValue.getMeters() ? previousValue : newValue;
|
||||
protected Distance compareValuesAndReturnNewResult(Distance currentResult, Distance newValue) {
|
||||
return currentResult.getMeters() <= newValue.getMeters() ? currentResult : newValue;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -45,8 +45,8 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getSpeedAtStart() {
|
||||
return getTrackedRace().getSpeed(getCompetitor(), 0);
|
||||
public Speed getSpeedWhenStarting() {
|
||||
return getTrackedRace().getSpeedWhenCrossingStartLine(getCompetitor());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import com.sap.sailing.domain.common.WindSourceType;
|
||||
public class WindSourceWithAdditionalID extends WindSourceImpl {
|
||||
private static final long serialVersionUID = -142955860536561690L;
|
||||
|
||||
private String id;
|
||||
private final String id;
|
||||
|
||||
public WindSourceWithAdditionalID(WindSourceType type, String id) {
|
||||
super(type);
|
||||
|
||||
+19
-11
@@ -79,20 +79,12 @@ public interface RaceLogTrackingAdapter {
|
||||
* @see #pingMark(RaceLog, Mark, GPSFix, RacingEventService) using a random {@link PingDeviceIdentifier}
|
||||
*/
|
||||
void pingMark(RaceLog raceLogToAddTo, Mark mark, GPSFix gpsFix, RacingEventService service);
|
||||
|
||||
|
||||
/**
|
||||
* @see #pingMark(RaceLog, Mark, GPSFix, RacingEventService)
|
||||
*/
|
||||
void pingMark(RegattaLog regattaLogToAddTo, Mark mark, GPSFix gpsFix, RacingEventService service);
|
||||
|
||||
/**
|
||||
* Duplicate the course and competitor registrations in the newest {@link RaceLogCourseDesignChangedEvent} in
|
||||
* {@code from} race log to the {@code to} race logs. The {@link Mark}s and {@link ControlPoint}s are duplicated and
|
||||
* not reused. This also inserts the necessary {@link RaceLogDefineMarkEvent}s into the {@code to} race logs.
|
||||
*/
|
||||
void copyCourseAndCompetitors(RaceLog from, Set<RaceLog> to, SharedDomainFactory baseDomainFactory,
|
||||
RacingEventService service);
|
||||
|
||||
/**
|
||||
* If not yet registered, register the competitors in {@code competitors}, and unregister all already registered
|
||||
* competitors not in {@code competitors}.
|
||||
@@ -107,15 +99,31 @@ public interface RaceLogTrackingAdapter {
|
||||
|
||||
/**
|
||||
* Invite competitors for tracking via the Tracking App by sending out emails.
|
||||
* @throws MailException
|
||||
*
|
||||
* @throws MailException
|
||||
*/
|
||||
void inviteCompetitorsForTrackingViaEmail(Event event, Leaderboard leaderboard,
|
||||
String serverUrlWithoutTrailingSlash, Set<Competitor> competitors, Locale locale) throws MailException;
|
||||
|
||||
/**
|
||||
* Invite buoy tenders for buoy pinging via the Buoy Tender App by sending out emails.
|
||||
* @throws MailException
|
||||
*
|
||||
* @throws MailException
|
||||
*/
|
||||
void inviteBuoyTenderViaEmail(Event event, Leaderboard leaderboard, String serverUrlWithoutTrailingSlash,
|
||||
String emails, Locale locale) throws MailException;
|
||||
|
||||
/**
|
||||
* Duplicate the course in the newest {@link RaceLogCourseDesignChangedEvent} in {@code from} race log to the
|
||||
* {@code to} race logs. The {@link Mark}s and {@link ControlPoint}s are duplicated and not reused. This also
|
||||
* inserts the necessary {@link RaceLogDefineMarkEvent}s into the {@code to} race logs.
|
||||
*/
|
||||
void copyCourse(RaceLog fromRaceLog, Set<RaceLog> toRaceLogs, SharedDomainFactory baseDomainFactory,
|
||||
RacingEventService service);
|
||||
|
||||
/**
|
||||
* Duplicate the competitor registrations from the {@code from} race log to the {@code to} race logs.
|
||||
*/
|
||||
void copyCompetitors(RaceLog from, Set<RaceLog> to,
|
||||
RacingEventService service);
|
||||
}
|
||||
+52
-39
@@ -92,8 +92,8 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceHandle startTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn, Fleet fleet)
|
||||
throws NotDenotedForRaceLogTrackingException, Exception {
|
||||
public RaceHandle startTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn,
|
||||
Fleet fleet) throws NotDenotedForRaceLogTrackingException, Exception {
|
||||
RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
RaceLogTrackingState raceLogTrackingState = new RaceLogTrackingStateAnalyzer(raceLog).analyze();
|
||||
if (!raceLogTrackingState.isForTracking()) {
|
||||
@@ -189,8 +189,8 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
}
|
||||
|
||||
private void revokeAlreadyDefinedMarks(RaceLog raceLog, AbstractLogEventAuthor author) {
|
||||
List<RaceLogEvent> markEvents = new AllEventsOfTypeFinder<>(raceLog, /* only unrevoked */ true, RaceLogDefineMarkEvent.class)
|
||||
.analyze();
|
||||
List<RaceLogEvent> markEvents = new AllEventsOfTypeFinder<>(raceLog, /* only unrevoked */true,
|
||||
RaceLogDefineMarkEvent.class).analyze();
|
||||
for (RaceLogEvent event : markEvents) {
|
||||
try {
|
||||
raceLog.revokeEvent(author, event, "removing mark that was already defined");
|
||||
@@ -201,36 +201,52 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyCourseAndCompetitors(RaceLog fromRaceLog, Set<RaceLog> toRaceLogs,
|
||||
SharedDomainFactory baseDomainFactory, RacingEventService service) {
|
||||
public void copyCourse(RaceLog fromRaceLog, Set<RaceLog> toRaceLogs, SharedDomainFactory baseDomainFactory,
|
||||
RacingEventService service) {
|
||||
CourseBase course = new LastPublishedCourseDesignFinder(fromRaceLog).analyze();
|
||||
final Set<Mark> marks = new HashSet<>();
|
||||
course.getWaypoints().forEach(wp->Util.addAll(wp.getMarks(), marks));
|
||||
final Set<Competitor> competitors = new RegisteredCompetitorsAnalyzer<>(fromRaceLog).analyze();
|
||||
final List<RaceLogEvent> raceLogDeviceMarkMappingEvents = new AllEventsOfTypeFinder<>(fromRaceLog, /* only unrevoked */ true, RaceLogDeviceMarkMappingEvent.class).analyze();
|
||||
if (course != null) {
|
||||
course.getWaypoints().forEach(wp -> Util.addAll(wp.getMarks(), marks));
|
||||
}
|
||||
|
||||
final List<RaceLogEvent> raceLogDeviceMarkMappingEvents = new AllEventsOfTypeFinder<>(fromRaceLog, /*
|
||||
* only
|
||||
* unrevoked
|
||||
*/true,
|
||||
RaceLogDeviceMarkMappingEvent.class).analyze();
|
||||
for (RaceLog toRaceLog : toRaceLogs) {
|
||||
if (course == null || !new RaceLogTrackingStateAnalyzer(toRaceLog).analyze().isForTracking()) {
|
||||
continue;
|
||||
if (new RaceLogTrackingStateAnalyzer(toRaceLog).analyze().isForTracking()) {
|
||||
if (course != null) {
|
||||
CourseBase newCourse = new CourseDataImpl("Copy of \"" + course.getName() + "\"");
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
int i = 0;
|
||||
revokeAlreadyDefinedMarks(toRaceLog, service.getServerAuthor());
|
||||
for (Waypoint oldWaypoint : course.getWaypoints()) {
|
||||
newCourse.addWaypoint(i++, oldWaypoint);
|
||||
}
|
||||
for (Mark mark : marks) {
|
||||
RaceLogEvent event = RaceLogEventFactory.INSTANCE.createDefineMarkEvent(now,
|
||||
service.getServerAuthor(), toRaceLog.getCurrentPassId(), mark);
|
||||
toRaceLog.add(event);
|
||||
}
|
||||
for (RaceLogEvent raceLogDeviceMarkMappingEvent : raceLogDeviceMarkMappingEvents) {
|
||||
toRaceLog.add(raceLogDeviceMarkMappingEvent);
|
||||
}
|
||||
int passId = toRaceLog.getCurrentPassId();
|
||||
RaceLogEvent newCourseEvent = RaceLogEventFactory.INSTANCE.createCourseDesignChangedEvent(now,
|
||||
service.getServerAuthor(), passId, newCourse);
|
||||
toRaceLog.add(newCourseEvent);
|
||||
}
|
||||
|
||||
}
|
||||
CourseBase newCourse = new CourseDataImpl("Copy of \"" + course.getName() + "\"");
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
int i = 0;
|
||||
revokeAlreadyDefinedMarks(toRaceLog, service.getServerAuthor());
|
||||
for (Waypoint oldWaypoint : course.getWaypoints()) {
|
||||
newCourse.addWaypoint(i++, oldWaypoint);
|
||||
}
|
||||
for (Mark mark : marks) {
|
||||
RaceLogEvent event = RaceLogEventFactory.INSTANCE.createDefineMarkEvent(now,
|
||||
service.getServerAuthor(), toRaceLog.getCurrentPassId(), mark);
|
||||
toRaceLog.add(event);
|
||||
}
|
||||
for (RaceLogEvent raceLogDeviceMarkMappingEvent : raceLogDeviceMarkMappingEvents) {
|
||||
toRaceLog.add(raceLogDeviceMarkMappingEvent);
|
||||
}
|
||||
int passId = toRaceLog.getCurrentPassId();
|
||||
RaceLogEvent newCourseEvent = RaceLogEventFactory.INSTANCE.createCourseDesignChangedEvent(now,
|
||||
service.getServerAuthor(), passId, newCourse);
|
||||
toRaceLog.add(newCourseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyCompetitors(RaceLog fromRaceLog, Set<RaceLog> toRaceLogs,
|
||||
RacingEventService service) {
|
||||
final Set<Competitor> competitors = new RegisteredCompetitorsAnalyzer<>(fromRaceLog).analyze();
|
||||
for (RaceLog toRaceLog : toRaceLogs) {
|
||||
registerCompetitors(service, toRaceLog, competitors);
|
||||
}
|
||||
}
|
||||
@@ -263,13 +279,10 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
|
||||
@Override
|
||||
public void pingMark(RegattaLog regattaLog, Mark mark, GPSFix gpsFix, RacingEventService service) {
|
||||
pingMark(
|
||||
regattaLog,
|
||||
mark,
|
||||
gpsFix,
|
||||
service,
|
||||
(DeviceIdentifier dev, TimePoint timePoint) -> new RegattaLogDeviceMarkMappingEventImpl(timePoint, service
|
||||
.getServerAuthor(), timePoint, UUID.randomUUID(), mark, dev, timePoint, timePoint), new PingDeviceIdentifierImpl());
|
||||
pingMark(regattaLog, mark, gpsFix, service,
|
||||
(DeviceIdentifier dev, TimePoint timePoint) -> new RegattaLogDeviceMarkMappingEventImpl(timePoint,
|
||||
service.getServerAuthor(), timePoint, UUID.randomUUID(), mark, dev, timePoint, timePoint),
|
||||
new PingDeviceIdentifierImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -415,9 +428,9 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
|
||||
String[] emailArray = emails.split(",");
|
||||
String leaderboardName = leaderboard.getName();
|
||||
|
||||
|
||||
String eventId = event.getId().toString();
|
||||
|
||||
|
||||
// http://<host>/buoy-tender/checkin?event_id=<event-id>&leaderboard_name=<leaderboard-name>
|
||||
String url = DeviceMappingConstants.getBuoyTenderInvitationUrl(serverUrlWithoutTrailingSlash, leaderboardName,
|
||||
eventId, NonGwtUrlHelper.INSTANCE);
|
||||
|
||||
+11
-5
@@ -123,8 +123,11 @@ extends TrackImpl<EventT> implements AbstractLog<EventT, VisitorT> {
|
||||
try {
|
||||
checkIfSuccessfullyRevokes(revokeEvent);
|
||||
lockForWrite();
|
||||
revokedEventIds.add(revokeEvent.getRevokedEventId());
|
||||
unlockAfterWrite();
|
||||
try {
|
||||
revokedEventIds.add(revokeEvent.getRevokedEventId());
|
||||
} finally {
|
||||
unlockAfterWrite();
|
||||
}
|
||||
} catch (NotRevokableException e) {
|
||||
logger.log(Level.WARNING, e.getMessage());
|
||||
}
|
||||
@@ -133,9 +136,12 @@ extends TrackImpl<EventT> implements AbstractLog<EventT, VisitorT> {
|
||||
|
||||
private void checkIfSuccessfullyRevokes(RevokeEvent<?> revokeEvent) throws NotRevokableException {
|
||||
lockForRead();
|
||||
EventT revokedEvent = getEventById(revokeEvent.getRevokedEventId());
|
||||
unlockAfterRead();
|
||||
|
||||
EventT revokedEvent;
|
||||
try {
|
||||
revokedEvent = getEventById(revokeEvent.getRevokedEventId());
|
||||
} finally {
|
||||
unlockAfterRead();
|
||||
}
|
||||
if (revokedEvent == null) {
|
||||
// it can happen that the event that has been revoked is not yet loaded - as we assume
|
||||
// that race log events never get removed we can safely continue and assume that
|
||||
|
||||
+4
-5
@@ -5,7 +5,6 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLog;
|
||||
import com.sap.sailing.domain.abstractlog.LogAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.MultiLogAnalyzer.AnalyzerFactory;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
@@ -13,15 +12,15 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDefineMarkEvent;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
|
||||
public class DefinedMarkFinder extends RaceLogAnalyzer<Collection<Mark>> {
|
||||
public DefinedMarkFinder(RaceLog raceLog) {
|
||||
public class RaceLogDefinedMarkFinder extends RaceLogAnalyzer<Collection<Mark>> {
|
||||
public RaceLogDefinedMarkFinder(RaceLog raceLog) {
|
||||
super(raceLog);
|
||||
}
|
||||
|
||||
public static class Factory implements AnalyzerFactory<Collection<Mark>> {
|
||||
@Override
|
||||
public LogAnalyzer<Collection<Mark>> createAnalyzer(AbstractLog<?, ?> log) {
|
||||
return new DefinedMarkFinder((RaceLog) log);
|
||||
public RaceLogAnalyzer<Collection<Mark>> createAnalyzer(AbstractLog<?, ?> log) {
|
||||
return new RaceLogDefinedMarkFinder((RaceLog) log);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ package com.sap.sailing.domain.abstractlog.shared.events;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.Revokable;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.DefinedMarkFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogDefinedMarkFinder;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||
@@ -19,7 +19,7 @@ import com.sap.sse.common.WithID;
|
||||
* If one end of the time range enclosed by {@link #getFrom()} and {@link #getTo()} is open, this can be closed
|
||||
* by a {@link CloseOpenEndedDeviceMappingEvent}.
|
||||
*
|
||||
* @see DefinedMarkFinder for rules by which {@link DeviceMapping}s are derived from these events.
|
||||
* @see RaceLogDefinedMarkFinder for rules by which {@link DeviceMapping}s are derived from these events.
|
||||
* @author Fredrik Teschke
|
||||
*/
|
||||
public interface DeviceMappingEvent<VisitorT, ItemType extends WithID> extends AbstractLogEvent<VisitorT>, Revokable {
|
||||
|
||||
+9
-9
@@ -41,15 +41,15 @@ public class CompetitorWithID implements Competitor {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CompetitorWithID [boatID=" + boatID + ", threeLetterIOCCode="
|
||||
+ threeLetterIOCCode + ", name=" + name + ", id=" + id + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CompetitorWithID [boatID=" + boatID + ", threeLetterIOCCode=" + threeLetterIOCCode + ", name=" + name
|
||||
+ ", id=" + id + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CrewMember> getCrew() {
|
||||
return crew;
|
||||
}
|
||||
@Override
|
||||
public List<CrewMember> getCrew() {
|
||||
return crew;
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -249,12 +249,12 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
private Iterable<Competitor> createCompetitorList(StartList startList, String raceId, BoatClass boatClass) {
|
||||
List<Competitor> result = new ArrayList<Competitor>();
|
||||
for (com.sap.sailing.domain.swisstimingadapter.Competitor swissTimingCompetitor : startList.getCompetitors()) {
|
||||
Competitor domainCompetitor;
|
||||
if(swissTimingCompetitor.getID() != null) {
|
||||
Competitor domainCompetitor;
|
||||
if (swissTimingCompetitor.getID() != null) {
|
||||
domainCompetitor = createCompetitorWithID(swissTimingCompetitor, boatClass);
|
||||
} else {
|
||||
} else {
|
||||
domainCompetitor = createCompetitorWithoutID(swissTimingCompetitor, raceId, boatClass);
|
||||
}
|
||||
}
|
||||
result.add(domainCompetitor);
|
||||
}
|
||||
return result;
|
||||
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
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.tracking.RaceLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
|
||||
import com.sap.sailing.domain.base.impl.FleetImpl;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.SeriesImpl;
|
||||
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sailing.domain.leaderboard.impl.CompetitorProviderFromRaceColumnsAndRegattaLike;
|
||||
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
|
||||
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||
import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithStartTimeAndRanks;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
/**
|
||||
* Tests the behavior of the class {@link CompetitorProviderFromRaceColumnsAndRegattaLike}, paying particular
|
||||
* attention to its caching and cache invalidation logic. When competitors are added to regatta logs or race logs
|
||||
* or when a tracked race is attached to a column or a column is added or removed, its caches need to be
|
||||
* invalidated and re-calculated accordingly.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class CompetitorProviderCacheInvalidationTest extends AbstractLeaderboardTest {
|
||||
private CompetitorProviderFromRaceColumnsAndRegattaLike competitorProviderFlexibleLeaderboard;
|
||||
private CompetitorProviderFromRaceColumnsAndRegattaLike competitorProviderRegattaLeaderboard;
|
||||
private FlexibleLeaderboardImpl flexibleLeaderboard;
|
||||
private RegattaLeaderboardImpl regattaLeaderboard;
|
||||
private RegattaImpl regatta;
|
||||
final int NUMBER_OF_COMP_LISTS = 4;
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Competitor>[] compLists = (List<Competitor>[]) new List<?>[NUMBER_OF_COMP_LISTS];
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final CourseAreaImpl courseArea = new CourseAreaImpl(
|
||||
"Test Course Area", UUID.randomUUID());
|
||||
flexibleLeaderboard = new FlexibleLeaderboardImpl("Test Flexible Leaderboard",
|
||||
new ThresholdBasedResultDiscardingRuleImpl(new int[0]), new LowPoint(), courseArea);
|
||||
competitorProviderFlexibleLeaderboard = new CompetitorProviderFromRaceColumnsAndRegattaLike(flexibleLeaderboard);
|
||||
regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, "Test Regatta", new BoatClassImpl("49er", BoatClassMasterdata._49ER), /* startDate */
|
||||
null, /* endDate */null, /* trackedRegattaRegistry */null, new LowPoint(), UUID.randomUUID(),
|
||||
courseArea);
|
||||
regattaLeaderboard = new RegattaLeaderboardImpl(regatta, new ThresholdBasedResultDiscardingRuleImpl(new int[0]));
|
||||
regatta.addSeries(new SeriesImpl("Test Series", /* isMedal */false, Arrays.asList(new FleetImpl("Yellow"),
|
||||
new FleetImpl("Blue")), Arrays.asList("R1", "R2", "R3"), /* trackedRegattaRegistry */null));
|
||||
for (int l = 0; l < NUMBER_OF_COMP_LISTS; l++) {
|
||||
compLists[l] = new ArrayList<Competitor>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
compLists[l].add(createCompetitor("" + l + "/" + i));
|
||||
}
|
||||
}
|
||||
competitorProviderRegattaLeaderboard = new CompetitorProviderFromRaceColumnsAndRegattaLike(regattaLeaderboard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnOneRaceInFlexibleLeaderboard() {
|
||||
TrackedRace trackedRace = new MockedTrackedRaceWithStartTimeAndRanks(MillisecondsTimePoint.now(), compLists[0]);
|
||||
flexibleLeaderboard.addRace(trackedRace, "R1", /* medalRace */ false);
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRace = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R1"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace);
|
||||
assertEquals(expected, actualForRace);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnOneRaceLogInFlexibleLeaderboard() {
|
||||
flexibleLeaderboard.addRaceColumn("R1", /* medalRace */ false);
|
||||
RaceLog raceLog = flexibleLeaderboard.getRacelog("R1", LeaderboardNameConstants.DEFAULT_FLEET_NAME);
|
||||
final int passId = 1;
|
||||
final LogEventAuthorImpl author = new LogEventAuthorImpl("Me", 0);
|
||||
final Map<Competitor, RaceLogRegisterCompetitorEvent> competitorOnRaceLogRegistrationEvents = new HashMap<>();
|
||||
for (Competitor c : compLists[0]) {
|
||||
final RaceLogRegisterCompetitorEvent registerCompetitorEvent = RaceLogEventFactory.INSTANCE.createRegisterCompetitorEvent(MillisecondsTimePoint.now(), author, passId, c);
|
||||
raceLog.add(registerCompetitorEvent);
|
||||
competitorOnRaceLogRegistrationEvents.put(c, registerCompetitorEvent);
|
||||
}
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRace = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R1"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace);
|
||||
assertEquals(expected, actualForRace);
|
||||
// we're now revoking a competitor registration on the race log and assert
|
||||
// that the competitor is gone from the list:
|
||||
final Competitor competitorToRevokeFromRaceLog = compLists[0].get(2);
|
||||
raceLog.add(RaceLogEventFactory.INSTANCE.createRevokeEvent(author, passId, competitorOnRaceLogRegistrationEvents.get(competitorToRevokeFromRaceLog), "Test revoking"));
|
||||
actualForRace = new HashSet<>(); // try another time; cache should of course yield an equal result (although
|
||||
// we're not asserting here that the result actually comes from the cache)
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R1"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace);
|
||||
expected.remove(competitorToRevokeFromRaceLog);
|
||||
assertEquals(expected.size(), actualForRace.size());
|
||||
assertEquals(expected, actualForRace);
|
||||
flexibleLeaderboard.removeRaceColumn("R1"); // test that changes to the race columns invalidate the cache
|
||||
flexibleLeaderboard.addRaceColumn("R1", /* medalRace */ false);
|
||||
actualForRace = new HashSet<>(); // try another time; cache should of course yield an equal result (although
|
||||
// we're not asserting here that the result actually comes from the cache)
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R1"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace);
|
||||
assertTrue(actualForRace.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnRegattaLogInFlexibleLeaderboard() {
|
||||
flexibleLeaderboard.addRaceColumn("R1", /* medalRace */ false);
|
||||
RegattaLog regattaLog = flexibleLeaderboard.getRegattaLog();
|
||||
for (Competitor c : compLists[0]) {
|
||||
regattaLog.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), new LogEventAuthorImpl("Me", 0), MillisecondsTimePoint.now(), UUID.randomUUID(), c));
|
||||
}
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRace = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R1"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace);
|
||||
assertEquals(expected, actualForRace);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnOneRaceLogAndRegattaLogInFlexibleLeaderboard() {
|
||||
flexibleLeaderboard.addRaceColumn("R1", /* medalRace */ false);
|
||||
RegattaLog regattaLog = flexibleLeaderboard.getRegattaLog();
|
||||
for (Competitor c : compLists[0]) {
|
||||
regattaLog.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), new LogEventAuthorImpl("Me", 0), MillisecondsTimePoint.now(), UUID.randomUUID(), c));
|
||||
}
|
||||
RaceLog raceLog = flexibleLeaderboard.getRacelog("R1", LeaderboardNameConstants.DEFAULT_FLEET_NAME);
|
||||
for (Competitor c : compLists[1]) {
|
||||
raceLog.add(RaceLogEventFactory.INSTANCE.createRegisterCompetitorEvent(MillisecondsTimePoint.now(), new LogEventAuthorImpl("Me", 0), 1, c));
|
||||
}
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
expected.addAll(compLists[1]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRace = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R1"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace);
|
||||
assertEquals(expected, actualForRace);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoCompetitorListsOnTwoRacesInFlexibleLeaderboard() {
|
||||
TrackedRace trackedRace1 = new MockedTrackedRaceWithStartTimeAndRanks(MillisecondsTimePoint.now(), compLists[0]);
|
||||
flexibleLeaderboard.addRace(trackedRace1, "R1", /* medalRace */ false);
|
||||
TrackedRace trackedRace2 = new MockedTrackedRaceWithStartTimeAndRanks(MillisecondsTimePoint.now(), compLists[1]);
|
||||
flexibleLeaderboard.addRace(trackedRace2, "R2", /* medalRace */ false);
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
expected.addAll(compLists[1]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRace1 = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R1"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace1);
|
||||
Set<Competitor> actualForRace2 = new HashSet<>();
|
||||
Util.addAll(competitorProviderFlexibleLeaderboard.getAllCompetitors(
|
||||
flexibleLeaderboard.getRaceColumnByName("R2"),
|
||||
flexibleLeaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME)), actualForRace2);
|
||||
assertEquals(new HashSet<>(compLists[0]), actualForRace1);
|
||||
assertEquals(new HashSet<>(compLists[1]), actualForRace2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnOneRaceInRegattaLeaderboard() {
|
||||
TrackedRace trackedRace = new MockedTrackedRaceWithStartTimeAndRanks(MillisecondsTimePoint.now(), compLists[0]);
|
||||
regattaLeaderboard.getRaceColumnByName("R1").setTrackedRace(regattaLeaderboard.getRaceColumnByName("R1").getFleetByName("Yellow"), trackedRace);
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRaceYellow = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
assertEquals(expected, actualForRaceYellow);
|
||||
Set<Competitor> actualForRaceBlue = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Blue")), actualForRaceBlue);
|
||||
assertEquals(Collections.emptySet(), actualForRaceBlue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoCompetitorListsOnTwoRacesInRegattaLeaderboard() {
|
||||
TrackedRace trackedRace1 = new MockedTrackedRaceWithStartTimeAndRanks(MillisecondsTimePoint.now(), compLists[0]);
|
||||
regattaLeaderboard.getRaceColumnByName("R1").setTrackedRace(regattaLeaderboard.getRaceColumnByName("R1").getFleetByName("Yellow"), trackedRace1);
|
||||
TrackedRace trackedRace2 = new MockedTrackedRaceWithStartTimeAndRanks(MillisecondsTimePoint.now(), compLists[1]);
|
||||
regattaLeaderboard.getRaceColumnByName("R1").setTrackedRace(regattaLeaderboard.getRaceColumnByName("R1").getFleetByName("Blue"), trackedRace2);
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
expected.addAll(compLists[1]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRaceYellow = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
assertEquals(new HashSet<>(compLists[0]), actualForRaceYellow);
|
||||
Set<Competitor> actualForRaceBlue = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Blue")), actualForRaceBlue);
|
||||
assertEquals(new HashSet<>(compLists[1]), actualForRaceBlue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnOneRaceLogInRegattaLeaderboard() {
|
||||
RaceLog raceLog = regattaLeaderboard.getRacelog("R1", "Yellow");
|
||||
for (Competitor c : compLists[0]) {
|
||||
raceLog.add(RaceLogEventFactory.INSTANCE.createRegisterCompetitorEvent(MillisecondsTimePoint.now(), new LogEventAuthorImpl("Me", 0), 1, c));
|
||||
}
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRaceYellow = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
assertEquals(new HashSet<>(compLists[0]), actualForRaceYellow);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnRegattaLogInRegattaLeaderboard() throws NotRevokableException {
|
||||
RegattaLog regattaLog = regattaLeaderboard.getRegatta().getRegattaLog();
|
||||
final Map<Competitor, RegattaLogRegisterCompetitorEvent> competitorOnRegattaLogRegistrationEvents = new HashMap<>();
|
||||
final LogEventAuthorImpl author = new LogEventAuthorImpl("Me", 0);
|
||||
for (Competitor c : compLists[0]) {
|
||||
final RegattaLogRegisterCompetitorEventImpl registerCompetitorEvent = new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), author, MillisecondsTimePoint.now(), UUID.randomUUID(), c);
|
||||
regattaLog.add(registerCompetitorEvent);
|
||||
competitorOnRegattaLogRegistrationEvents.put(c, registerCompetitorEvent);
|
||||
}
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualForRaceYellow = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
assertEquals(new HashSet<>(compLists[0]), actualForRaceYellow);
|
||||
Set<Competitor> actualForRaceBlue = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Blue")), actualForRaceBlue);
|
||||
assertEquals(new HashSet<>(compLists[0]), actualForRaceBlue);
|
||||
// now revoke one registration again from the regatta log
|
||||
final Competitor competitorToRevokeFromRegattaLog = compLists[0].get(2);
|
||||
regattaLog.revokeEvent(author, competitorOnRegattaLogRegistrationEvents.get(competitorToRevokeFromRegattaLog));
|
||||
actualForRaceYellow = new HashSet<>(); // try another time; cache should of course yield an equal result (although
|
||||
// we're not asserting here that the result actually comes from the cache)
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
expected.remove(competitorToRevokeFromRegattaLog);
|
||||
assertEquals(expected.size(), actualForRaceYellow.size());
|
||||
assertEquals(expected, actualForRaceYellow);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleCompetitorListOnOneRaceLogAndRegattaLogInRegattaLeaderboard() {
|
||||
final RegattaLog regattaLog = regattaLeaderboard.getRegatta().getRegattaLog();
|
||||
final LogEventAuthorImpl author = new LogEventAuthorImpl("Me", 0);
|
||||
for (Competitor c : compLists[0]) {
|
||||
regattaLog.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), author, MillisecondsTimePoint.now(), UUID.randomUUID(), c));
|
||||
}
|
||||
final RaceLog raceLog = regattaLeaderboard.getRacelog("R1", "Yellow");
|
||||
final int passId = 1;
|
||||
final Map<Competitor, RaceLogRegisterCompetitorEvent> competitorOnRaceLogRegistrationEvents = new HashMap<>();
|
||||
for (Competitor c : compLists[passId]) {
|
||||
final RaceLogRegisterCompetitorEvent registerCompetitorEvent = RaceLogEventFactory.INSTANCE.createRegisterCompetitorEvent(MillisecondsTimePoint.now(), author, passId, c);
|
||||
raceLog.add(registerCompetitorEvent);
|
||||
competitorOnRaceLogRegistrationEvents.put(c, registerCompetitorEvent);
|
||||
}
|
||||
regattaLeaderboard.setSuppressed(compLists[0].get(compLists[0].size()-passId), /* suppressed */ true);
|
||||
Set<Competitor> expected = new HashSet<>(compLists[0]);
|
||||
expected.addAll(compLists[passId]);
|
||||
Set<Competitor> expectedWithoutSuppressed = new HashSet<>(expected);
|
||||
expectedWithoutSuppressed.remove(compLists[0].get(compLists[0].size()-passId));
|
||||
Set<Competitor> actual = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(), actual);
|
||||
assertEquals(expected, actual);
|
||||
Set<Competitor> actualWithoutSuppressed = new HashSet<>();
|
||||
Util.addAll(regattaLeaderboard.getCompetitors(), actualWithoutSuppressed);
|
||||
assertEquals(expectedWithoutSuppressed, actualWithoutSuppressed);
|
||||
Set<Competitor> actualForRaceYellow = new HashSet<>();
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
assertEquals(expected, actualForRaceYellow);
|
||||
actualForRaceYellow = new HashSet<>(); // try another time; cache should of course yield an equal result (although
|
||||
// we're not asserting here that the result actually comes from the cache)
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
assertEquals(expected, actualForRaceYellow);
|
||||
// But now it gets interesting: we're revoking a competitor registration on the race log and assert
|
||||
// that the competitor is gone from the list:
|
||||
final Competitor competitorToRevokeFromRaceLog = compLists[passId].get(2);
|
||||
raceLog.add(RaceLogEventFactory.INSTANCE.createRevokeEvent(author, passId, competitorOnRaceLogRegistrationEvents.get(competitorToRevokeFromRaceLog), "Test revoking"));
|
||||
actualForRaceYellow = new HashSet<>(); // try another time; cache should of course yield an equal result (although
|
||||
// we're not asserting here that the result actually comes from the cache)
|
||||
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
|
||||
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
|
||||
expected.remove(competitorToRevokeFromRaceLog);
|
||||
assertEquals(expected.size(), actualForRaceYellow.size());
|
||||
assertEquals(expected, actualForRaceYellow);
|
||||
}
|
||||
|
||||
}
|
||||
+13
-13
@@ -95,8 +95,8 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
|
||||
flexibleLeaderboard.addRace(trackedRace, RACECOLUMN_FLEXIBLELEADERBOARD+"2", false);
|
||||
Wind wind = new WindImpl(new DegreePosition(12, 13), startOfSecondRace.plus(Duration.ONE_MINUTE), new KnotSpeedWithBearingImpl(
|
||||
/* speedInKnots */18, new DegreeBearingImpl(185)));
|
||||
assertTrue(previousTrackedRace.takesWindFix(wind)); // previous race has tracking still open and takes the fix
|
||||
assertTrue(trackedRace.takesWindFix(wind)); // tracked race also needs to take the fix as it falls into the regular tracking interval
|
||||
assertTrue(previousTrackedRace.takesWindFixWithTimePoint(wind.getTimePoint())); // previous race has tracking still open and takes the fix
|
||||
assertTrue(trackedRace.takesWindFixWithTimePoint(wind.getTimePoint())); // tracked race also needs to take the fix as it falls into the regular tracking interval
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -117,8 +117,8 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
|
||||
Wind wind = new WindImpl(new DegreePosition(12, 13),
|
||||
endOfFirstRace.plus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS).plus(Duration.ONE_MINUTE), // fix is after the grace period
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185)));
|
||||
assertFalse(previousTrackedRace.takesWindFix(wind)); // previous race has tracking closed one second after it started and doesn't accept the fix
|
||||
assertTrue(trackedRace.takesWindFix(wind)); // tracked race also needs to take the fix as it falls into the regular tracking interval
|
||||
assertFalse(previousTrackedRace.takesWindFixWithTimePoint(wind.getTimePoint())); // previous race has tracking closed one second after it started and doesn't accept the fix
|
||||
assertTrue(trackedRace.takesWindFixWithTimePoint(wind.getTimePoint())); // tracked race also needs to take the fix as it falls into the regular tracking interval
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,7 +134,7 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
|
||||
Wind wind = new WindImpl(new DegreePosition(12, 13),
|
||||
endOfFirstRace.plus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS).plus(Duration.ONE_MINUTE), // fix is after the grace period
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185)));
|
||||
assertTrue(trackedRace.takesWindFix(wind));
|
||||
assertTrue(trackedRace.takesWindFixWithTimePoint(wind.getTimePoint()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -154,8 +154,8 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
|
||||
Wind wind = new WindImpl(new DegreePosition(12, 13),
|
||||
endOfFirstRace.plus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS).plus(Duration.ONE_MINUTE), // fix is after the grace period
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185)));
|
||||
assertFalse(previousTrackedRace.takesWindFix(wind)); // fix is after first race's end plus grace period
|
||||
assertFalse(trackedRace.takesWindFix(wind));
|
||||
assertFalse(previousTrackedRace.takesWindFixWithTimePoint(wind.getTimePoint())); // fix is after first race's end plus grace period
|
||||
assertFalse(trackedRace.takesWindFixWithTimePoint(wind.getTimePoint()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -175,8 +175,8 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
|
||||
Wind wind = new WindImpl(new DegreePosition(12, 13),
|
||||
startOfFirstRace.plus(Duration.ONE_SECOND), // fix is recorded by previous race
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185)));
|
||||
assertTrue(previousTrackedRace.takesWindFix(wind)); // fix is after first race's end plus grace period
|
||||
assertFalse(trackedRace.takesWindFix(wind));
|
||||
assertTrue(previousTrackedRace.takesWindFixWithTimePoint(wind.getTimePoint())); // fix is after first race's end plus grace period
|
||||
assertFalse(trackedRace.takesWindFixWithTimePoint(wind.getTimePoint()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -244,9 +244,9 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
|
||||
r2.setTrackedRace(fleet, tr1);
|
||||
r3.setTrackedRace(fleet, tr2);
|
||||
r4.setTrackedRace(fleet, tr3); // produce a cycle because now transitively tr1 has itself as a predecessor
|
||||
assertTrue(tr3.takesWindFix(new WindImpl(new DegreePosition(12, 13),
|
||||
assertTrue(tr3.takesWindFixWithTimePoint(new WindImpl(new DegreePosition(12, 13),
|
||||
startOfThirdRace.minus(TrackedRaceImpl.EXTRA_LONG_TIME_BEFORE_START_TO_TRACK_WIND_MILLIS.divide(2)),
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185)))));
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185))).getTimePoint()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,9 +265,9 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
|
||||
final TrackedRace tr1 = createTrackedRace("FirstRace", startOfFirstRace, endOfFirstRace);
|
||||
r1.setTrackedRace(fleet, tr1);
|
||||
r2.setTrackedRace(fleet, tr1);
|
||||
assertTrue(tr1.takesWindFix(new WindImpl(new DegreePosition(12, 13),
|
||||
assertTrue(tr1.takesWindFixWithTimePoint(new WindImpl(new DegreePosition(12, 13),
|
||||
startOfFirstRace.minus(TrackedRaceImpl.EXTRA_LONG_TIME_BEFORE_START_TO_TRACK_WIND_MILLIS.divide(2)),
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185)))));
|
||||
new KnotSpeedWithBearingImpl(/* speedInKnots */18, new DegreeBearingImpl(185))).getTimePoint()));
|
||||
}
|
||||
|
||||
private DynamicTrackedRace createTrackedRace(final String name, final TimePoint startOfRace, final TimePoint endOfRace) {
|
||||
|
||||
+16
@@ -49,6 +49,7 @@ import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.ranking.RankingMetricConstructor;
|
||||
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
|
||||
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
|
||||
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
||||
@@ -471,6 +472,21 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
public RaceColumn getRaceColumnByName(String raceColumnName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsRegattaLike getRegattaLike() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceLog getRacelog(String raceColumnName, String fleetName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends RaceColumn> getRaceColumns() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+9
-24
@@ -28,7 +28,6 @@ import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Nationality;
|
||||
import com.sap.sailing.domain.base.Person;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Sideline;
|
||||
@@ -105,8 +104,6 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
|
||||
private final Map<com.sap.sse.common.Util.Pair<String, UUID>, DynamicPerson> personCache = new HashMap<>();
|
||||
|
||||
private final Map<Serializable, DynamicTeam> teamCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Caches regattas by their name and their boat class's name
|
||||
*/
|
||||
@@ -262,7 +259,7 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
nationality = null;
|
||||
logger.log(Level.SEVERE, "Unknown nationality "+nationalityAsString+" for competitor "+name+"; leaving null", iae);
|
||||
}
|
||||
DynamicTeam team = getOrCreateTeam(name, nationality, competitorId);
|
||||
DynamicTeam team = createTeam(name, nationality, competitorId);
|
||||
DynamicBoat boat = new BoatImpl(shortName, boatClass, shortName);
|
||||
result = competitorStore.getOrCreateCompetitor(competitorId, name, null /* displayColor */,
|
||||
null /* email */, null /* flagImag */, team, boat, (double) timeOnTimeFactor,
|
||||
@@ -271,27 +268,15 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a team called <code>name</code> already is known by this domain factory, it is returned. Otherwise, the team name
|
||||
* is split along "+" signs with one {@link Person} object created for each part. If an existing team is found, its
|
||||
* nationality will be updated to match <code>nationality</code>.
|
||||
*/
|
||||
private DynamicTeam getOrCreateTeam(String name, Nationality nationality, UUID competitorId) {
|
||||
synchronized (teamCache) {
|
||||
DynamicTeam result = teamCache.get(competitorId);
|
||||
if (result == null) {
|
||||
String[] sailorNames = name.split("\\b*\\+\\b*");
|
||||
List<DynamicPerson> sailors = new ArrayList<DynamicPerson>();
|
||||
for (String sailorName : sailorNames) {
|
||||
sailors.add(getOrCreatePerson(sailorName.trim(), nationality, competitorId));
|
||||
}
|
||||
result = new TeamImpl(name, sailors, /* TODO coach not known */null);
|
||||
teamCache.put(competitorId, result);
|
||||
} else {
|
||||
result.setNationality(nationality);
|
||||
}
|
||||
return result;
|
||||
private DynamicTeam createTeam(String name, Nationality nationality, UUID competitorId) {
|
||||
DynamicTeam result;
|
||||
String[] sailorNames = name.split("\\b*\\+\\b*");
|
||||
List<DynamicPerson> sailors = new ArrayList<DynamicPerson>();
|
||||
for (String sailorName : sailorNames) {
|
||||
sailors.add(getOrCreatePerson(sailorName.trim(), nationality, competitorId));
|
||||
}
|
||||
result = new TeamImpl(name, sailors, /* TODO coach not known */null);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.MetaLeaderboard;
|
||||
@@ -227,4 +228,18 @@ public interface RaceColumn extends Named {
|
||||
boolean hasSplitFleets();
|
||||
|
||||
RaceExecutionOrderProvider getRaceExecutionOrderProvider();
|
||||
|
||||
/**
|
||||
* Provides the combined set of competitors from all {@link #getTrackedRace(Fleet) tracked races attached to this
|
||||
* column} or, in case a fleet does not have a tracked race attached, the competitors registered through the
|
||||
* respective {@link RaceLog} {@link #getRaceLog(Fleet) attached to this column for that fleet}. Note that this does
|
||||
* not include competitors registered through any {@link RegattaLog} on the structure owning (directly or
|
||||
* transitively) this column.
|
||||
*/
|
||||
Iterable<Competitor> getAllCompetitors();
|
||||
|
||||
/**
|
||||
* Same as {@link #getAllCompetitors()}, but restricted to the single race identified by the <code>fleet</code> parameter.
|
||||
*/
|
||||
Iterable<Competitor> getAllCompetitors(Fleet fleet);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
||||
import com.sap.sailing.domain.common.RankingMetrics;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaIdentifier;
|
||||
import com.sap.sailing.domain.leaderboard.HasRaceColumnsAndRegattaLike;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.ranking.RankingMetricConstructor;
|
||||
import com.sap.sailing.domain.ranking.RankingMetricsFactory;
|
||||
@@ -22,7 +23,7 @@ import com.sap.sse.common.WithID;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface Regatta extends Named, WithID, IsRegattaLike {
|
||||
public interface Regatta extends Named, WithID, IsRegattaLike, HasRaceColumnsAndRegattaLike {
|
||||
ScoringScheme getScoringScheme();
|
||||
|
||||
/**
|
||||
|
||||
+43
-3
@@ -3,11 +3,14 @@ package com.sap.sailing.domain.base.impl;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
@@ -117,9 +120,9 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
|
||||
|
||||
@Override
|
||||
public Fleet getFleetOfCompetitor(Competitor competitor) {
|
||||
for (Map.Entry<Fleet, TrackedRace> e : trackedRaces.entrySet()) {
|
||||
if (Util.contains(e.getValue().getRace().getCompetitors(), competitor)) {
|
||||
return e.getKey();
|
||||
for (final Fleet fleet : getFleets()) {
|
||||
if (Util.contains(getAllCompetitors(fleet), competitor)) {
|
||||
return fleet;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -206,4 +209,41 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
|
||||
public void setMasterDataExportOngoingThreadFlag(boolean flagValue) {
|
||||
trackedRaces.setMasterDataExportOngoingThreadFlag(flagValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors() {
|
||||
Set<Competitor> result = new HashSet<>();
|
||||
for (Fleet fleet : getFleets()) {
|
||||
TrackedRace trackedRace = getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
Util.addAll(trackedRace.getRace().getCompetitors(), result);
|
||||
} else {
|
||||
// if no tracked race is found, use competitors from race log; this assumes that if a tracked
|
||||
// race exists, its competitors set takes precedence over what's in the race log. Usually,
|
||||
// the tracked race will have the same competitors as those in the race log, or more because
|
||||
// those from the regatta log are added to the tracked race as well.
|
||||
Set<Competitor> viaRaceLog = new RegisteredCompetitorsAnalyzer<>(getRaceLog(fleet)).analyze();
|
||||
result.addAll(viaRaceLog);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors(final Fleet fleet) {
|
||||
final Iterable<Competitor> result;
|
||||
TrackedRace trackedRace = getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
result = trackedRace.getRace().getCompetitors();
|
||||
} else {
|
||||
// if no tracked race is found, use competitors from race log; this assumes that if a tracked
|
||||
// race exists, its competitors set takes precedence over what's in the race log. Usually,
|
||||
// the tracked race will have the same competitors as those in the race log, or more because
|
||||
// those from the regatta log are added to the tracked race as well.
|
||||
Set<Competitor> viaRaceLog = new RegisteredCompetitorsAnalyzer<>(getRaceLog(fleet)).analyze();
|
||||
result = viaRaceLog;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,9 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
@@ -40,6 +40,7 @@ import com.sap.sailing.domain.common.RegattaName;
|
||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.leaderboard.impl.CompetitorProviderFromRaceColumnsAndRegattaLike;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
@@ -111,6 +112,8 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
* Defaults to <code>true</code>. See {@link Regatta#useStartTimeInference()}.
|
||||
*/
|
||||
private boolean useStartTimeInference;
|
||||
|
||||
private transient CompetitorProviderFromRaceColumnsAndRegattaLike competitorsProvider;
|
||||
|
||||
/**
|
||||
* Constructs a regatta with an empty {@link RaceLogStore}.
|
||||
@@ -171,7 +174,6 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
* @param series
|
||||
* all {@link Series} in this iterable will have their {@link Series#setRegatta(Regatta) regatta set} to
|
||||
* this new regatta.
|
||||
* @param rankingMetricConstructor TODO
|
||||
*/
|
||||
public <S extends Series> RegattaImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
String name, BoatClass boatClass, TimePoint startDate, TimePoint endDate, Iterable<S> series, boolean persistent, ScoringScheme scoringScheme,
|
||||
@@ -363,24 +365,15 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors() {
|
||||
Set<Competitor> result = new HashSet<Competitor>();
|
||||
if (competitorsProvider == null) {
|
||||
competitorsProvider = new CompetitorProviderFromRaceColumnsAndRegattaLike(this);
|
||||
}
|
||||
Util.addAll(competitorsProvider.getAllCompetitors(), result);
|
||||
for (RaceDefinition race : getAllRaces()) {
|
||||
for (Competitor c : race.getCompetitors()) {
|
||||
result.add(c);
|
||||
}
|
||||
}
|
||||
for (Series series : getSeries()) {
|
||||
for (RaceColumn rc : series.getRaceColumns()) {
|
||||
for (Fleet fleet : rc.getFleets()) {
|
||||
TrackedRace trackedRace = rc.getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
Util.addAll(trackedRace.getRace().getCompetitors(), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//consider {@link RegattaLog}
|
||||
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(regattaLikeHelper.getRegattaLog()).analyze();
|
||||
result.addAll(viaLog);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -700,4 +693,37 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
public RaceColumn getRaceColumnByName(String raceColumnName) {
|
||||
return regattaLikeHelper.getRaceColumnByName(raceColumnName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsRegattaLike getRegattaLike() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceLog getRacelog(String raceColumnName, String fleetName) {
|
||||
final RaceLog result;
|
||||
final RaceColumn raceColumn = getRaceColumnByName(raceColumnName);
|
||||
if (raceColumn == null) {
|
||||
result = null;
|
||||
} else {
|
||||
final Fleet fleet = raceColumn.getFleetByName(fleetName);
|
||||
if (fleet == null) {
|
||||
result = null;
|
||||
} else {
|
||||
result = raceColumn.getRaceLog(fleet);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends RaceColumn> getRaceColumns() {
|
||||
final List<RaceColumnInSeries> result = new ArrayList<>();
|
||||
for (final Series series : getSeries()) {
|
||||
for (final RaceColumnInSeries rc : series.getRaceColumns()) {
|
||||
result.add(rc);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.sap.sailing.domain.leaderboard;
|
||||
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
|
||||
public interface HasRaceColumns {
|
||||
Iterable<? extends RaceColumn> getRaceColumns();
|
||||
|
||||
void addRaceColumnListener(RaceColumnListener listener);
|
||||
|
||||
void removeRaceColumnListener(RaceColumnListener listener);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.sap.sailing.domain.leaderboard;
|
||||
|
||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||
|
||||
public interface HasRaceColumnsAndRegattaLike extends HasRegattaLike, HasRaceColumns {
|
||||
|
||||
}
|
||||
+18
-2
@@ -44,7 +44,7 @@ import com.sap.sse.common.Util;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface Leaderboard extends LeaderboardBase {
|
||||
public interface Leaderboard extends LeaderboardBase, HasRaceColumns {
|
||||
/**
|
||||
* If the leaderboard is a "matrix" with the cells being defined by a competitor / race "coordinate,"
|
||||
* then this interface defines the structure of the "cells."
|
||||
@@ -93,6 +93,22 @@ public interface Leaderboard extends LeaderboardBase {
|
||||
* @return all competitors in this leaderboard, including the suppressed ones.
|
||||
*/
|
||||
Iterable<Competitor> getAllCompetitors();
|
||||
|
||||
/**
|
||||
* Retrieves all competitors expected to race in the fleet and column specified.
|
||||
* When a {@link TrackedRace} is {@link RaceColumn#getTrackedRace(Fleet) attached} to the race
|
||||
* column for the <code>fleet</code> specified, its competitor set is returned. Otherwise,
|
||||
* the competitors are collected from any other information, such as a regatta log and/or the
|
||||
* race log for the combination of race column and fleet or, in case of a meta-leaderboard,
|
||||
* from the leaderboard represented by the race column.
|
||||
*/
|
||||
Iterable<Competitor> getAllCompetitors(RaceColumn raceColumn, Fleet fleet);
|
||||
|
||||
/**
|
||||
* Same as {@link #getAllCompetitors(RaceColumn, Fleet)} with competitors from {@link #getSuppressedCompetitors()}
|
||||
* removed
|
||||
*/
|
||||
Iterable<Competitor> getCompetitors(RaceColumn raceColumn, Fleet fleet);
|
||||
|
||||
/**
|
||||
* Convenience method which returns the difference between {@link #getAllCompetitors()} and {@link #getCompetitors()}.
|
||||
@@ -247,7 +263,7 @@ public interface Leaderboard extends LeaderboardBase {
|
||||
* Sums up the {@link #getTotalPoints(Competitor, TrackedRace, TimePoint) total points} of <code>competitor</code>
|
||||
* across all races tracked by this leaderboard, respecting the {@link RaceColumn#isStartsWithZeroScore()} property.
|
||||
*/
|
||||
Double getTotalPoints(Competitor competitor, TimePoint timePoint) throws NoWindException;
|
||||
Double getTotalPoints(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* Sums up the {@link #getTotalPoints(Competitor, RaceColumn, TimePoint) total points} of <code>competitor</code>
|
||||
|
||||
+7
-67
@@ -8,7 +8,6 @@ import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorChangeListener;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
@@ -16,9 +15,9 @@ import com.sap.sailing.domain.base.Nationality;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.base.WithNationality;
|
||||
import com.sap.sailing.domain.base.impl.RaceColumnListenerWithDefaultAction;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardCache;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||
@@ -262,9 +261,14 @@ public class LeaderboardCacheManager {
|
||||
leaderboard.getScoreCorrection().addScoreCorrectionListener(scoreCorrectionListener);
|
||||
scoreCorrectionListeners.put(leaderboard, scoreCorrectionListener);
|
||||
competitorChangeListeners.put(leaderboard, competitorChangeListener);
|
||||
final RaceColumnListener raceColumnListener = new RaceColumnListener() {
|
||||
final RaceColumnListener raceColumnListener = new RaceColumnListenerWithDefaultAction() {
|
||||
private static final long serialVersionUID = 8165124797028386317L;
|
||||
|
||||
@Override
|
||||
public void defaultAction() {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackedRaceLinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
removeFromCache(leaderboard);
|
||||
@@ -278,70 +282,6 @@ public class LeaderboardCacheManager {
|
||||
public boolean isTransient() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
removeFromCache(leaderboard); // removes all listeners from invalidationListenersPerLeaderboard and from their TrackedRaces
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isMedalRaceChanged(RaceColumn raceColumn, boolean newIsMedalRace) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isStartsWithZeroScoreChanged(RaceColumn raceColumn, boolean newIsStartsWithZeroScore) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasSplitFleetContiguousScoringChanged(RaceColumn raceColumn, boolean hasSplitFleetContiguousScoring) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isFirstColumnIsNonDiscardableCarryForwardChanged(RaceColumn raceColumn,
|
||||
boolean firstColumnIsNonDiscardableCarryForward) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceColumnAddedToContainer(RaceColumn raceColumn) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceColumnRemovedFromContainer(RaceColumn raceColumn) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceColumnMoved(RaceColumn raceColumn, int newIndex) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule,
|
||||
ResultDiscardingRule newDiscardingRule) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void competitorDisplayNameChanged(Competitor competitor, String oldDisplayName,
|
||||
String displayName) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier,
|
||||
RaceLogEvent event) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
};
|
||||
leaderboard.addRaceColumnListener(raceColumnListener);
|
||||
synchronized (raceColumnListeners) {
|
||||
|
||||
+18
-28
@@ -12,9 +12,9 @@ import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.leaderboard.HasRaceColumnsAndRegattaLike;
|
||||
import com.sap.sailing.domain.leaderboard.ScoreCorrection;
|
||||
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
|
||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
@@ -28,14 +28,14 @@ import com.sap.sse.common.TimePoint;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardImpl implements HasRegattaLike{
|
||||
public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardImpl implements HasRaceColumnsAndRegattaLike {
|
||||
private static final long serialVersionUID = -328091952760083438L;
|
||||
|
||||
|
||||
/**
|
||||
* Cache for the combined competitors of this leaderboard; taken from the {@link TrackedRace#getRace() races of the
|
||||
* tracked races} associated with this leaderboard. Updated when the set of tracked races changes.
|
||||
*/
|
||||
private transient Iterable<Competitor> allCompetitorsCache;
|
||||
private transient CompetitorProviderFromRaceColumnsAndRegattaLike competitorsProvider;
|
||||
|
||||
/**
|
||||
* @param scoreComparator the comparator to use to compare basic scores, such as net points
|
||||
@@ -77,20 +77,21 @@ public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardI
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors() {
|
||||
if (allCompetitorsCache == null) {
|
||||
Set<Competitor> result = new HashSet<Competitor>();
|
||||
synchronized (this) {
|
||||
for (TrackedRace r : getTrackedRaces()) {
|
||||
for (Competitor c : r.getRace().getCompetitors()) {
|
||||
result.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
allCompetitorsCache = result;
|
||||
}
|
||||
return allCompetitorsCache;
|
||||
return getOrCreateCompetitorsProvider().getAllCompetitors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors(RaceColumn raceColumn, Fleet fleet) {
|
||||
return getOrCreateCompetitorsProvider().getAllCompetitors(raceColumn, fleet);
|
||||
}
|
||||
|
||||
private CompetitorProviderFromRaceColumnsAndRegattaLike getOrCreateCompetitorsProvider() {
|
||||
if (competitorsProvider == null) {
|
||||
competitorsProvider = new CompetitorProviderFromRaceColumnsAndRegattaLike(this);
|
||||
}
|
||||
return competitorsProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getCompetitorByIdAsString(String idAsString) {
|
||||
for (Competitor competitor : getAllCompetitors()) {
|
||||
@@ -144,18 +145,6 @@ public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardI
|
||||
return correctedRank;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackedRaceLinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
allCompetitorsCache = null;
|
||||
super.trackedRaceLinked(raceColumn, fleet, trackedRace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
allCompetitorsCache = null;
|
||||
super.trackedRaceUnlinked(raceColumn, fleet, trackedRace);
|
||||
}
|
||||
|
||||
// Note: no need to redefine isMedalRaceChanged because that doesn't affect the competitorsCache
|
||||
|
||||
@Override
|
||||
@@ -182,4 +171,5 @@ public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardI
|
||||
Fleet fleet = raceColumn.getFleetByName(fleetName);
|
||||
return raceColumn.getRaceLog(fleet);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-3
@@ -12,7 +12,6 @@ import java.util.Set;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
@@ -182,8 +181,7 @@ public abstract class AbstractScoringSchemeImpl implements ScoringScheme {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareByLatestRegattaInMetaLeaderboard(Leaderboard leaderboard, Competitor o1, Competitor o2,
|
||||
TimePoint timePoint) throws NoWindException {
|
||||
public int compareByLatestRegattaInMetaLeaderboard(Leaderboard leaderboard, Competitor o1, Competitor o2, TimePoint timePoint) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+60
-25
@@ -14,6 +14,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -516,13 +517,13 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getTotalPoints(Competitor competitor, TimePoint timePoint) throws NoWindException {
|
||||
public Double getTotalPoints(Competitor competitor, TimePoint timePoint) {
|
||||
return getTotalPoints(competitor, getRaceColumns(), timePoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getTotalPoints(Competitor competitor, final Iterable<RaceColumn> raceColumnsToConsider,
|
||||
TimePoint timePoint) throws NoWindException {
|
||||
TimePoint timePoint) {
|
||||
// when a column with isStartsWithZeroScore() is found, only reset score if the competitor scored in any race from there on
|
||||
boolean needToResetScoreUponNextNonEmptyEntry = false;
|
||||
double result = getCarriedPoints(competitor);
|
||||
@@ -720,11 +721,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
public Map<Competitor, Double> call() {
|
||||
Map<Competitor, Double> totalPointsSumPerCompetitorInColumn = new HashMap<>();
|
||||
for (Competitor competitor : getCompetitors()) {
|
||||
try {
|
||||
totalPointsSumPerCompetitorInColumn.put(competitor, getTotalPoints(competitor, finalRaceColumnsToConsider, timePoint));
|
||||
} catch (NoWindException e) {
|
||||
throw new NoWindError(e);
|
||||
}
|
||||
totalPointsSumPerCompetitorInColumn.put(competitor, getTotalPoints(competitor, finalRaceColumnsToConsider, timePoint));
|
||||
}
|
||||
synchronized (result) {
|
||||
return totalPointsSumPerCompetitorInColumn;
|
||||
@@ -1096,31 +1093,69 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors() {
|
||||
// TODO bug 1348: try to cache result; invalidation would have to listen for columns added and suppression changing;
|
||||
// for meta-leaderbaords, transitive listening to those events would be necessary.
|
||||
Set<Competitor> result = new HashSet<>();
|
||||
for (Competitor competitor : getAllCompetitors()) {
|
||||
if (!isSuppressed(competitor)) {
|
||||
result.add(competitor);
|
||||
}
|
||||
final Iterable<Competitor> result;
|
||||
// mostly the set of suppressed competitors is empty; in this case, avoid having to loop over the
|
||||
// potentially large set of competitors
|
||||
if (Util.isEmpty(getSuppressedCompetitors())) {
|
||||
result = getAllCompetitors();
|
||||
} else {
|
||||
final Iterable<Competitor> allCompetitors = getAllCompetitors();
|
||||
final Set<Competitor> suppressed = new HashSet<>();
|
||||
Util.addAll(getSuppressedCompetitors(), suppressed);
|
||||
result = getCompetitorIterableSkippingSuppressed(allCompetitors, suppressed);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors(RaceColumn raceColumn, Fleet fleet) {
|
||||
return getCompetitorIterableSkippingSuppressed(getAllCompetitors(raceColumn, fleet), getSuppressedCompetitors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the difference between {@link #getCompetitors} and {@link #getAllCompetitors}. If a competitor is suppressed,
|
||||
* it won't participate in the scoring process, particularly because it isn't considered by {@link #getCompetitorsFromBestToWorst(TimePoint)}
|
||||
* nor {@link #getCompetitorsFromBestToWorst(RaceColumn, TimePoint)}.
|
||||
* return an iterable with a smart iterator that filters out the suppressed elements on demand
|
||||
*/
|
||||
private boolean isSuppressed(Competitor competitor) {
|
||||
LockUtil.lockForRead(suppressedCompetitorsLock);
|
||||
try {
|
||||
return suppressedCompetitors.contains(competitor);
|
||||
} finally {
|
||||
LockUtil.unlockAfterRead(suppressedCompetitorsLock);
|
||||
}
|
||||
protected Iterable<Competitor> getCompetitorIterableSkippingSuppressed(final Iterable<Competitor> allCompetitors,
|
||||
final Iterable<Competitor> suppressed) {
|
||||
final Iterable<Competitor> result;
|
||||
result = new Iterable<Competitor>() {
|
||||
@Override
|
||||
public Iterator<Competitor> iterator() {
|
||||
return new Iterator<Competitor>() {
|
||||
private final Iterator<Competitor> allIter = allCompetitors.iterator();
|
||||
private Competitor next = advance();
|
||||
|
||||
private Competitor advance() {
|
||||
next = null;
|
||||
while (allIter.hasNext() && next == null) {
|
||||
next = allIter.next();
|
||||
if (Util.contains(suppressed, next)) {
|
||||
next = null;
|
||||
}
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor next() {
|
||||
if (next == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
final Competitor result = next;
|
||||
advance();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getSuppressedCompetitors() {
|
||||
LockUtil.lockForRead(suppressedCompetitorsLock);
|
||||
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
package com.sap.sailing.domain.leaderboard.impl;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.impl.BaseRegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.base.impl.RaceColumnListenerWithDefaultAction;
|
||||
import com.sap.sailing.domain.leaderboard.HasRaceColumnsAndRegattaLike;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
/**
|
||||
* A caching provider of a competitor set, based on the tracked races and {@link RaceLog}s of the {@link RaceColumn}s of
|
||||
* a {@link HasRaceColumnsAndRegattaLike} and the {@link RegattaLog} of the same object. After an answer has been provided,
|
||||
* it is cached. The cache is invalidated when one of the following events occurs:
|
||||
* <ul>
|
||||
* <li>a competitor is registered with or unregistered from a race log of any of the race columns or the regatta log</li>
|
||||
* <li>a race column is added or removed</li>
|
||||
* <li>a tracked race is linked to or unlinked from any of the race columns</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class CompetitorProviderFromRaceColumnsAndRegattaLike {
|
||||
private static final Logger logger = Logger.getLogger(CompetitorProviderFromRaceColumnsAndRegattaLike.class.getName());
|
||||
|
||||
private final HasRaceColumnsAndRegattaLike provider;
|
||||
|
||||
private final RegattaLogEventVisitor regattaLogCompetitorsCacheInvalidationListener;
|
||||
|
||||
private final RaceLogEventVisitor raceLogCompetitorsCacheInvalidationListener;
|
||||
|
||||
private final RaceColumnListener raceColumnListener;
|
||||
|
||||
private Iterable<Competitor> allCompetitorsCache;
|
||||
|
||||
private final ConcurrentHashMap<Pair<RaceColumn, Fleet>, Iterable<Competitor>> allCompetitorsCacheByRace;
|
||||
|
||||
public CompetitorProviderFromRaceColumnsAndRegattaLike(HasRaceColumnsAndRegattaLike provider) {
|
||||
super();
|
||||
this.provider = provider;
|
||||
this.allCompetitorsCacheByRace = new ConcurrentHashMap<>();
|
||||
// A note regarding listener serializability: RaceLogListener and RegattaLogListener objects
|
||||
// don't need to be serializable as the log listeners are a transient structure. The race column
|
||||
// listeners, however, need to explicitly declare that they are transient.
|
||||
// This enclosing object is intended not to be serialized and shall be re-constructed by
|
||||
// its users after de-serialization. Therefore, the transient-ness of the log listeners works
|
||||
// as intended, and the race column listener explicitly returns true from its isTransient()
|
||||
// method.
|
||||
regattaLogCompetitorsCacheInvalidationListener = new BaseRegattaLogEventVisitor() {
|
||||
@Override
|
||||
public void visit(RegattaLogRegisterCompetitorEvent event) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogRevokeEvent event) {
|
||||
try {
|
||||
if (RegattaLogRegisterCompetitorEvent.class.isAssignableFrom(Class.forName(event.getRevokedEventType()))) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.WARNING, "Problem occurred trying to resolve revoked event class "+event.getRevokedEventType(), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
raceLogCompetitorsCacheInvalidationListener = new BaseRaceLogEventVisitor() {
|
||||
@Override
|
||||
public void visit(RaceLogRegisterCompetitorEvent event) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogRevokeEvent event) {
|
||||
try {
|
||||
if (RaceLogRegisterCompetitorEvent.class.isAssignableFrom(Class.forName(event.getRevokedEventType()))) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.WARNING, "Problem occurred trying to resolve revoked event class "+event.getRevokedEventType(), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
raceColumnListener = new RaceColumnListenerWithDefaultAction() {
|
||||
private static final long serialVersionUID = -8678230058730043052L;
|
||||
|
||||
@Override
|
||||
public void defaultAction() {}
|
||||
|
||||
/**
|
||||
* As the entire provider object is considered transient, its listeners are so, too.
|
||||
*/
|
||||
@Override
|
||||
public boolean isTransient() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackedRaceLinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceColumnAddedToContainer(RaceColumn raceColumn) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceColumnRemovedFromContainer(RaceColumn raceColumn) {
|
||||
invalidateAllCompetitorsCaches();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Iterable<Competitor> getAllCompetitors() {
|
||||
if (allCompetitorsCache == null) {
|
||||
final Set<Competitor> result = new HashSet<>();
|
||||
for (RaceColumn rc : provider.getRaceColumns()) {
|
||||
Util.addAll(rc.getAllCompetitors(), result);
|
||||
for (final Fleet fleet : rc.getFleets()) {
|
||||
rc.getRaceLog(fleet).addListener(raceLogCompetitorsCacheInvalidationListener);
|
||||
}
|
||||
}
|
||||
provider.addRaceColumnListener(raceColumnListener);
|
||||
// consider {@link RegattaLog}
|
||||
Set<Competitor> viaLog = getCompetitorsFromRegattaLogAndRegisterAsRegattaLogListener();
|
||||
result.addAll(viaLog);
|
||||
allCompetitorsCache = result;
|
||||
}
|
||||
return allCompetitorsCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains competitors from the regatta log and adds those from the tracked race for the
|
||||
* raceColumn/fleet combination or the race log, if no tracked race is attached for this
|
||||
* combination. Does <em>not</em> eliminate suppressed competitors.
|
||||
*/
|
||||
public Iterable<Competitor> getAllCompetitors(final RaceColumn raceColumn, final Fleet fleet) {
|
||||
Pair<RaceColumn, Fleet> key = new Pair<>(raceColumn, fleet);
|
||||
Iterable<Competitor> result = allCompetitorsCacheByRace.get(key);
|
||||
if (result == null) {
|
||||
final Set<Competitor> resultSet = new HashSet<>();
|
||||
Util.addAll(raceColumn.getAllCompetitors(fleet), resultSet);
|
||||
// note: adding listeners is idempotent; at most one occurrence of this listener exists in the race log's listeners set
|
||||
raceColumn.getRaceLog(fleet).addListener(raceLogCompetitorsCacheInvalidationListener);
|
||||
provider.addRaceColumnListener(raceColumnListener);
|
||||
// consider {@link RegattaLog}
|
||||
Set<Competitor> viaLog = getCompetitorsFromRegattaLogAndRegisterAsRegattaLogListener();
|
||||
resultSet.addAll(viaLog);
|
||||
result = resultSet;
|
||||
allCompetitorsCacheByRace.put(key, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<Competitor> getCompetitorsFromRegattaLogAndRegisterAsRegattaLogListener() {
|
||||
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(provider.getRegattaLike().getRegattaLog()).analyze();
|
||||
// note: adding listeners is idempotent; at most one occurrence of this listener exists in the regatta log's listeners set
|
||||
provider.getRegattaLike().getRegattaLog().addListener(regattaLogCompetitorsCacheInvalidationListener);
|
||||
return viaLog;
|
||||
}
|
||||
|
||||
private void invalidateAllCompetitorsCaches() {
|
||||
allCompetitorsCache = null;
|
||||
// note: adding listeners was idempotent; at most one occurrence of this listener exists in the regatta log's listeners set
|
||||
provider.getRegattaLike().getRegattaLog().removeListener(regattaLogCompetitorsCacheInvalidationListener);
|
||||
for (final RaceColumn rc : provider.getRaceColumns()) {
|
||||
for (final Fleet fleet : rc.getFleets()) {
|
||||
// note: adding listeners was idempotent; at most one occurrence of this listener exists in the race log's listeners set
|
||||
rc.getRaceLog(fleet).removeListener(raceLogCompetitorsCacheInvalidationListener);
|
||||
}
|
||||
}
|
||||
// note: adding listeners was idempotent; at most one occurrence of this listener exists in the race column listeners set
|
||||
provider.removeRaceColumnListener(raceColumnListener);
|
||||
allCompetitorsCacheByRace.clear(); // this is a little coarse-grained; but given the typical access patterns it should be good enough.
|
||||
// The change frequency of competitors lists on individual races is much lower than the access frequency to this structure.
|
||||
}
|
||||
|
||||
}
|
||||
+4
-17
@@ -8,14 +8,11 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
@@ -145,8 +142,10 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
|
||||
private FlexibleRaceColumn addRaceColumn(String name, boolean medalRace, boolean logAlreadyExistingColumn) {
|
||||
FlexibleRaceColumn column = getRaceColumnByName(name);
|
||||
if (column != null) {
|
||||
final String msg = "Trying to create race column with duplicate name "+name+" in leaderboard "+getName();
|
||||
logger.severe(msg);
|
||||
if (logAlreadyExistingColumn) {
|
||||
final String msg = "Trying to create race column with duplicate name " + name + " in leaderboard " + getName();
|
||||
logger.severe(msg);
|
||||
}
|
||||
} else {
|
||||
column = createRaceColumn(name, medalRace);
|
||||
column.addRaceColumnListener(this);
|
||||
@@ -319,18 +318,6 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
|
||||
return regattaLikeHelper.getTimeOnDistanceAllowancePerNauticalMile(competitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors() {
|
||||
Set<Competitor> result = new HashSet<>();
|
||||
for (Competitor c : super.getAllCompetitors()) {
|
||||
result.add(c);
|
||||
}
|
||||
//consider {@link RegattaLog}
|
||||
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(regattaLikeHelper.getRegattaLog()).analyze();
|
||||
result.addAll(viaLog);
|
||||
return result;
|
||||
}
|
||||
|
||||
private class RaceExecutionOrderCache extends AbstractRaceExecutionOrderProvider {
|
||||
private static final long serialVersionUID = 652833386555762661L;
|
||||
|
||||
|
||||
+1
-2
@@ -107,8 +107,7 @@ public class HighPointExtremeSailingSeriesOverall extends HighPoint {
|
||||
* @throws NoWindException
|
||||
*/
|
||||
@Override
|
||||
public int compareByLatestRegattaInMetaLeaderboard(Leaderboard leaderboard,
|
||||
Competitor o1, Competitor o2, TimePoint timePoint) throws NoWindException {
|
||||
public int compareByLatestRegattaInMetaLeaderboard(Leaderboard leaderboard, Competitor o1, Competitor o2, TimePoint timePoint) {
|
||||
assert leaderboard instanceof MetaLeaderboard;
|
||||
// compare by last regatta if this leaderboard is a meta leaderboard
|
||||
final int result;
|
||||
|
||||
+16
-5
@@ -110,10 +110,11 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) {
|
||||
needToResetO1ScoreUponNextValidResult = raceColumn.isStartsWithZeroScore();
|
||||
needToResetO2ScoreUponNextValidResult = raceColumn.isStartsWithZeroScore();
|
||||
if (getLeaderboard().getScoringScheme().isValidInTotalScore(getLeaderboard(), raceColumn, o1, timePoint)
|
||||
&& getLeaderboard().getScoringScheme().isValidInTotalScore(getLeaderboard(), raceColumn, o2, timePoint)) {
|
||||
int preemptiveColumnResult = 0;
|
||||
final Double o1Score = totalPointsCache.get(new Util.Pair<Competitor, RaceColumn>(o1, raceColumn));
|
||||
final boolean o1ValidInTotalScore = getLeaderboard().getScoringScheme().isValidInTotalScore(getLeaderboard(), raceColumn, o1, timePoint);
|
||||
final boolean o2ValidInTotalScore = getLeaderboard().getScoringScheme().isValidInTotalScore(getLeaderboard(), raceColumn, o2, timePoint);
|
||||
final Double o1Score;
|
||||
if (o1ValidInTotalScore) {
|
||||
o1Score = totalPointsCache.get(new Util.Pair<Competitor, RaceColumn>(o1, raceColumn));
|
||||
if (o1Score != null) {
|
||||
o1Scores.add(new Util.Pair<RaceColumn, Double>(raceColumn, o1Score));
|
||||
if (needToResetO1ScoreUponNextValidResult) {
|
||||
@@ -122,7 +123,12 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
}
|
||||
o1ScoreSum += o1Score;
|
||||
}
|
||||
final Double o2Score = totalPointsCache.get(new Util.Pair<Competitor, RaceColumn>(o2, raceColumn));
|
||||
} else {
|
||||
o1Score = null;
|
||||
}
|
||||
final Double o2Score;
|
||||
if (o2ValidInTotalScore) {
|
||||
o2Score = totalPointsCache.get(new Util.Pair<Competitor, RaceColumn>(o2, raceColumn));
|
||||
if (o2Score != null) {
|
||||
o2Scores.add(new Util.Pair<RaceColumn, Double>(raceColumn, o2Score));
|
||||
if (needToResetO2ScoreUponNextValidResult) {
|
||||
@@ -131,6 +137,11 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
}
|
||||
o2ScoreSum += o2Score;
|
||||
}
|
||||
} else {
|
||||
o2Score = null;
|
||||
}
|
||||
if (o1ValidInTotalScore && o2ValidInTotalScore) {
|
||||
int preemptiveColumnResult = 0;
|
||||
if (raceColumn.isMedalRace()) {
|
||||
// only count the score for the medal race score if it wasn't a carry-forward column
|
||||
if (!raceColumn.isCarryForward()) {
|
||||
|
||||
+12
@@ -5,6 +5,7 @@ import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -147,6 +148,17 @@ public abstract class AbstractMetaLeaderboard extends AbstractSimpleLeaderboardI
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors(RaceColumn raceColumn, Fleet fleet) {
|
||||
final Iterable<Competitor> result;
|
||||
if (fleet == metaFleet && Util.contains(getRaceColumns(), raceColumn)) {
|
||||
result = ((MetaLeaderboardColumn) raceColumn).getAllCompetitors();
|
||||
} else {
|
||||
result = Collections.emptySet();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fleet getFleet(String fleetName) {
|
||||
return fleetName.equals(metaFleet.getName()) ? metaFleet : null;
|
||||
|
||||
+16
@@ -203,4 +203,20 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R
|
||||
public RaceExecutionOrderProvider getRaceExecutionOrderProvider() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors() {
|
||||
return leaderboard.getAllCompetitors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getAllCompetitors(Fleet fleet) {
|
||||
final Iterable<Competitor> result;
|
||||
if (fleet == metaFleet) {
|
||||
result = leaderboard.getAllCompetitors();
|
||||
} else {
|
||||
result = Collections.emptySet();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.regattalike;
|
||||
|
||||
import com.sap.sailing.domain.leaderboard.HasRaceColumnsAndRegattaLike;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
|
||||
public interface LeaderboardThatHasRegattaLike extends Leaderboard, HasRegattaLike {
|
||||
public interface LeaderboardThatHasRegattaLike extends Leaderboard, HasRaceColumnsAndRegattaLike {
|
||||
}
|
||||
@@ -299,11 +299,11 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
* implementations shall override this and provide a meaningful implementation according to the specification given
|
||||
* above.
|
||||
*/
|
||||
default boolean takesWindFix(Wind wind) {
|
||||
default boolean takesWindFixWithTimePoint(TimePoint timePoint) {
|
||||
return true;
|
||||
}
|
||||
|
||||
default boolean takesWindFixRecursively(Wind wind, Set<TrackedRace> visited) {
|
||||
default boolean takesWindFixWithTimePointRecursively(TimePoint windFixTimePoint, Set<TrackedRace> visited) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -676,7 +676,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
@Override
|
||||
public boolean recordWind(Wind wind, WindSource windSource) {
|
||||
final boolean result;
|
||||
if (takesWindFix(wind)) {
|
||||
if (takesWindFixWithTimePoint(wind.getTimePoint())) {
|
||||
result = getOrCreateWindTrack(windSource).add(wind);
|
||||
updated(/* time point */null); // wind events shouldn't advance race time
|
||||
triggerManeuverCacheRecalculationForAllCompetitors();
|
||||
|
||||
+11
-11
@@ -54,7 +54,7 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogGateLineOpeningTimeEv
|
||||
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRacingProcedure;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.DefinedMarkFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogDefinedMarkFinder;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.DeviceMarkMappingFinder;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
@@ -1570,10 +1570,10 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
* two is not <code>null</code>.
|
||||
*/
|
||||
@Override
|
||||
public boolean takesWindFix(Wind wind) {
|
||||
public boolean takesWindFixWithTimePoint(TimePoint timePoint) {
|
||||
final Set<TrackedRace> visited = new HashSet<>();
|
||||
visited.add(this);
|
||||
return takesWindFixRecursively(wind, visited);
|
||||
return takesWindFixWithTimePointRecursively(timePoint, visited);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1582,7 +1582,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
* {@link RaceExecutionOrderProvider}
|
||||
*/
|
||||
@Override
|
||||
public boolean takesWindFixRecursively(Wind wind, Set<TrackedRace> visited) {
|
||||
public boolean takesWindFixWithTimePointRecursively(TimePoint windFixTimePoint, Set<TrackedRace> visited) {
|
||||
final boolean result;
|
||||
final TimePoint earliestStartTimePoint = Util.getEarliestOfTimePoints(getStartOfRace(), getStartOfTracking());
|
||||
final TimePoint latestEndTimePoint = Util.getLatestOfTimePoints(getEndOfRace(), getEndOfTracking());
|
||||
@@ -1590,21 +1590,21 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
// first check if the fix meets the criteria set by the latestEndTimePoint: either the latestEndTimePoint is null, meaning an
|
||||
// open interval which will continue to accept late wind fixes, or the fix time point is before the latestEndTimePoint plus a grace
|
||||
// interval:
|
||||
if (latestEndTimePoint == null || wind.getTimePoint().minus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS).before(latestEndTimePoint)) {
|
||||
if (latestEndTimePoint == null || windFixTimePoint.minus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS).before(latestEndTimePoint)) {
|
||||
// then check, if fix is accepted anyway because it's after earliestStartTimePoint.minus(TIME_BEFORE_START_TO_TRACK_WIND_MILLIS)
|
||||
// and before latestEndTimePoint.plus(IS_LIVE_GRACE_PERIOD_IN_MILLIS) or latestEndTimePoint is null. In this case, no expensive
|
||||
// recursive check whether previous races take the fix are required.
|
||||
if (wind.getTimePoint().plus(TIME_BEFORE_START_TO_TRACK_WIND_MILLIS).after(earliestStartTimePoint)) {
|
||||
if (windFixTimePoint.plus(TIME_BEFORE_START_TO_TRACK_WIND_MILLIS).after(earliestStartTimePoint)) {
|
||||
result = true;
|
||||
} else {
|
||||
// if the fix is older than even the extended lead interval would accept, don't accept the fix:
|
||||
if (wind.getTimePoint().plus(EXTRA_LONG_TIME_BEFORE_START_TO_TRACK_WIND_MILLIS).before(earliestStartTimePoint)) {
|
||||
if (windFixTimePoint.plus(EXTRA_LONG_TIME_BEFORE_START_TO_TRACK_WIND_MILLIS).before(earliestStartTimePoint)) {
|
||||
result = false;
|
||||
} else {
|
||||
// the fix is in the critical interval between EXTRA_LONG_TIME_BEFORE_START_TO_TRACK_WIND_MILLIS and
|
||||
// TIME_BEFORE_START_TO_TRACK_WIND_MILLIS before the earliestStartTimePoint; the fix shall only be accepted
|
||||
// if no previous race exists that accepts it
|
||||
result = noPreviousRaceTakesWind(wind, visited);
|
||||
result = noPreviousRaceTakesWindFixWithTimePoint(windFixTimePoint, visited);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1616,11 +1616,11 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean noPreviousRaceTakesWind(Wind wind, Set<TrackedRace> visited) {
|
||||
private boolean noPreviousRaceTakesWindFixWithTimePoint(TimePoint timePoint, Set<TrackedRace> visited) {
|
||||
final boolean result;
|
||||
Set<TrackedRace> previousRacesInExecutionOrder = getPreviousRacesFromAttachedRaceExecutionOrderProviders();
|
||||
if (previousRacesInExecutionOrder == null || !previousRacesInExecutionOrder.stream().filter(tr ->
|
||||
visited.add(tr) && tr.takesWindFixRecursively(wind, visited)).findAny().isPresent()) {
|
||||
visited.add(tr) && tr.takesWindFixWithTimePointRecursively(timePoint, visited)).findAny().isPresent()) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
@@ -3874,7 +3874,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
new MapWithValueCollectionReducer<>(), allLogs).analyze();
|
||||
final Set<Mark> result = new HashSet<>();
|
||||
result.addAll(markMappings.keySet());
|
||||
final AnalyzerFactory<Collection<Mark>> analyzerFactory = new DefinedMarkFinder.Factory();
|
||||
final AnalyzerFactory<Collection<Mark>> analyzerFactory = new RaceLogDefinedMarkFinder.Factory();
|
||||
Set<Mark> marksDefinedInRaceLog = new MultiLogAnalyzer<>(analyzerFactory, new SetReducer<Mark>(), raceLogs).analyze();
|
||||
result.addAll(marksDefinedInRaceLog);
|
||||
return result;
|
||||
|
||||
+4
-4
@@ -7,10 +7,10 @@ import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.gwt.home.client.shared.Countdown;
|
||||
import com.sap.sailing.gwt.home.client.shared.Countdown.CountdownListener;
|
||||
import com.sap.sailing.gwt.home.client.shared.Countdown.RemainingTime;
|
||||
import com.sap.sailing.gwt.home.client.shared.Countdown.Unit;
|
||||
import com.sap.sailing.gwt.home.shared.utils.Countdown;
|
||||
import com.sap.sailing.gwt.home.shared.utils.Countdown.CountdownListener;
|
||||
import com.sap.sailing.gwt.home.shared.utils.Countdown.RemainingTime;
|
||||
import com.sap.sailing.gwt.home.shared.utils.Countdown.Unit;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/sailing-fontface-1.0.cache.css">
|
||||
<script src="js/jquery-1.11.1.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="js/jquery.slick/slick-1.5.5.css"/>
|
||||
<script type="text/javascript" src="js/jquery.slick/slick-1.5.5.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="js/jquery.slick/slick-1.5.8.css"/>
|
||||
<script type="text/javascript" src="js/jquery.slick/slick-1.5.8.min.js"></script>
|
||||
<link href="js/video-js/video-js.css" rel="stylesheet">
|
||||
<link href="js/video-js/video-js-sapsailing.css" rel="stylesheet">
|
||||
<script src="js/video-js/video.js"></script>
|
||||
|
||||
@@ -19,44 +19,42 @@
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.polars.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.annotations/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.operationaltransformation/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.replication/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/Home.html com.sap.sailing.gwt.ui.Search -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart.html com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/Home.html com.sap.sailing.gwt.ui.Search -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart.html com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -XX:MaxPermSize=512m -Xdebug -Xrunjdwp:transport=dt_socket,address=7999,server=y"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread -Xmx2048m -XX:MaxPermSize=512m -Xdebug -Xrunjdwp:transport=dt_socket,address=7999,server=y"/>
|
||||
</launchConfiguration>
|
||||
@@ -75,5 +75,5 @@
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir "${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work" -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Desktop com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread -Xms1024m -Xmx3072m"/>
|
||||
</launchConfiguration>
|
||||
@@ -10,6 +10,7 @@
|
||||
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
|
||||
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
|
||||
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
|
||||
@@ -44,7 +45,6 @@
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.polars.datamining.shared/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/>
|
||||
@@ -65,13 +65,12 @@
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.ui/src/main/java" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.annotations/src" path="3" type="2"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war "${project_loc:com.sap.sailing.gwt.ui}" -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
|
||||
</launchConfiguration>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
_ _ _ _
|
||||
___| (_) ___| | __ (_)___
|
||||
/ __| | |/ __| |/ / | / __|
|
||||
\__ \ | | (__| < _ | \__ \
|
||||
|___/_|_|\___|_|\_(_)/ |___/
|
||||
|__/
|
||||
|
||||
Version: 1.5.0
|
||||
Author: Ken Wheeler
|
||||
Website: http://kenwheeler.github.io
|
||||
Docs: http://kenwheeler.github.io/slick
|
||||
Repo: http://github.com/kenwheeler/slick
|
||||
Issues: http://github.com/kenwheeler/slick/issues
|
||||
|
||||
*/
|
||||
/* global window, document, define, jQuery, setInterval, clearInterval */
|
||||
|
||||
!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";var b=window.Slick||{};b=function(){function c(c,d){var f,g,h,e=this;if(e.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:a(c),appendDots:a(c),arrows:!0,asNavFor:null,prevArrow:'<button type="button" data-role="none" class="slick-prev" aria-label="previous">Previous</button>',nextArrow:'<button type="button" data-role="none" class="slick-next" aria-label="next">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(a,b){return'<button type="button" data-role="none">'+(b+1)+"</button>"},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0},e.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,$list:null,touchObject:{},transformsEnabled:!1},a.extend(e,e.initials),e.activeBreakpoint=null,e.animType=null,e.animProp=null,e.breakpoints=[],e.breakpointSettings=[],e.cssTransitions=!1,e.hidden="hidden",e.paused=!1,e.positionProp=null,e.respondTo=null,e.rowCount=1,e.shouldClick=!0,e.$slider=a(c),e.$slidesCache=null,e.transformType=null,e.transitionType=null,e.visibilityChange="visibilitychange",e.windowWidth=0,e.windowTimer=null,f=a(c).data("slick")||{},e.options=a.extend({},e.defaults,f,d),e.currentSlide=e.options.initialSlide,e.originalSettings=e.options,g=e.options.responsive||null,g&&g.length>-1){e.respondTo=e.options.respondTo||"window";for(h in g)g.hasOwnProperty(h)&&(e.breakpoints.push(g[h].breakpoint),e.breakpointSettings[g[h].breakpoint]=g[h].settings);e.breakpoints.sort(function(a,b){return e.options.mobileFirst===!0?a-b:b-a})}"undefined"!=typeof document.mozHidden?(e.hidden="mozHidden",e.visibilityChange="mozvisibilitychange"):"undefined"!=typeof document.msHidden?(e.hidden="msHidden",e.visibilityChange="msvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(e.hidden="webkitHidden",e.visibilityChange="webkitvisibilitychange"),e.autoPlay=a.proxy(e.autoPlay,e),e.autoPlayClear=a.proxy(e.autoPlayClear,e),e.changeSlide=a.proxy(e.changeSlide,e),e.clickHandler=a.proxy(e.clickHandler,e),e.selectHandler=a.proxy(e.selectHandler,e),e.setPosition=a.proxy(e.setPosition,e),e.swipeHandler=a.proxy(e.swipeHandler,e),e.dragHandler=a.proxy(e.dragHandler,e),e.keyHandler=a.proxy(e.keyHandler,e),e.autoPlayIterator=a.proxy(e.autoPlayIterator,e),e.instanceUid=b++,e.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,e.init(),e.checkResponsive(!0)}var b=0;return c}(),b.prototype.addSlide=b.prototype.slickAdd=function(b,c,d){var e=this;if("boolean"==typeof c)d=c,c=null;else if(0>c||c>=e.slideCount)return!1;e.unload(),"number"==typeof c?0===c&&0===e.$slides.length?a(b).appendTo(e.$slideTrack):d?a(b).insertBefore(e.$slides.eq(c)):a(b).insertAfter(e.$slides.eq(c)):d===!0?a(b).prependTo(e.$slideTrack):a(b).appendTo(e.$slideTrack),e.$slides=e.$slideTrack.children(this.options.slide),e.$slideTrack.children(this.options.slide).detach(),e.$slideTrack.append(e.$slides),e.$slides.each(function(b,c){a(c).attr("data-slick-index",b)}),e.$slidesCache=e.$slides,e.reinit()},b.prototype.animateHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.animate({height:b},a.options.speed)}},b.prototype.animateSlide=function(b,c){var d={},e=this;e.animateHeight(),e.options.rtl===!0&&e.options.vertical===!1&&(b=-b),e.transformsEnabled===!1?e.options.vertical===!1?e.$slideTrack.animate({left:b},e.options.speed,e.options.easing,c):e.$slideTrack.animate({top:b},e.options.speed,e.options.easing,c):e.cssTransitions===!1?(e.options.rtl===!0&&(e.currentLeft=-e.currentLeft),a({animStart:e.currentLeft}).animate({animStart:b},{duration:e.options.speed,easing:e.options.easing,step:function(a){a=Math.ceil(a),e.options.vertical===!1?(d[e.animType]="translate("+a+"px, 0px)",e.$slideTrack.css(d)):(d[e.animType]="translate(0px,"+a+"px)",e.$slideTrack.css(d))},complete:function(){c&&c.call()}})):(e.applyTransition(),b=Math.ceil(b),d[e.animType]=e.options.vertical===!1?"translate3d("+b+"px, 0px, 0px)":"translate3d(0px,"+b+"px, 0px)",e.$slideTrack.css(d),c&&setTimeout(function(){e.disableTransition(),c.call()},e.options.speed))},b.prototype.asNavFor=function(b){var c=this,d=nLine truncated
|
||||
if(!(b.options.swipe===!1||"ontouchend"in document&&b.options.swipe===!1||b.options.draggable===!1&&-1!==a.type.indexOf("mouse")))switch(b.touchObject.fingerCount=a.originalEvent&&void 0!==a.originalEvent.touches?a.originalEvent.touches.length:1,b.touchObject.minSwipe=b.listWidth/b.options.touchThreshold,b.options.verticalSwiping===!0&&(b.touchObject.minSwipe=b.listHeight/b.options.touchThreshold),a.data.action){case"start":b.swipeStart(a);break;case"move":b.swipeMove(a);break;case"end":b.swipeEnd(a)}},b.prototype.swipeMove=function(a){var d,e,f,g,h,b=this;return h=void 0!==a.originalEvent?a.originalEvent.touches:null,!b.dragging||h&&1!==h.length?!1:(d=b.getLeft(b.currentSlide),b.touchObject.curX=void 0!==h?h[0].pageX:a.clientX,b.touchObject.curY=void 0!==h?h[0].pageY:a.clientY,b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curX-b.touchObject.startX,2))),b.options.verticalSwiping===!0&&(b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curY-b.touchObject.startY,2)))),e=b.swipeDirection(),"vertical"!==e?(void 0!==a.originalEvent&&b.touchObject.swipeLength>4&&a.preventDefault(),g=(b.options.rtl===!1?1:-1)*(b.touchObject.curX>b.touchObject.startX?1:-1),b.options.verticalSwiping===!0&&(g=b.touchObject.curY>b.touchObject.startY?1:-1),f=b.touchObject.swipeLength,b.touchObject.edgeHit=!1,b.options.infinite===!1&&(0===b.currentSlide&&"right"===e||b.currentSlide>=b.getDotCount()&&"left"===e)&&(f=b.touchObject.swipeLength*b.options.edgeFriction,b.touchObject.edgeHit=!0),b.swipeLeft=b.options.vertical===!1?d+f*g:d+f*(b.$list.height()/b.listWidth)*g,b.options.verticalSwiping===!0&&(b.swipeLeft=d+f*g),b.options.fade===!0||b.options.touchMove===!1?!1:b.animating===!0?(b.swipeLeft=null,!1):(b.setCSS(b.swipeLeft),void 0)):void 0)},b.prototype.swipeStart=function(a){var c,b=this;return 1!==b.touchObject.fingerCount||b.slideCount<=b.options.slidesToShow?(b.touchObject={},!1):(void 0!==a.originalEvent&&void 0!==a.originalEvent.touches&&(c=a.originalEvent.touches[0]),b.touchObject.startX=b.touchObject.curX=void 0!==c?c.pageX:a.clientX,b.touchObject.startY=b.touchObject.curY=void 0!==c?c.pageY:a.clientY,b.dragging=!0,void 0)},b.prototype.unfilterSlides=b.prototype.slickUnfilter=function(){var a=this;null!==a.$slidesCache&&(a.unload(),a.$slideTrack.children(this.options.slide).detach(),a.$slidesCache.appendTo(a.$slideTrack),a.reinit())},b.prototype.unload=function(){var b=this;a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&"object"!=typeof b.options.prevArrow&&b.$prevArrow.remove(),b.$nextArrow&&"object"!=typeof b.options.nextArrow&&b.$nextArrow.remove(),b.$slides.removeClass("slick-slide slick-active slick-visible").attr("aria-hidden","true").css("width","")},b.prototype.unslick=function(){var a=this;a.destroy()},b.prototype.updateArrows=function(){var b,a=this;b=Math.floor(a.options.slidesToShow/2),a.options.arrows===!0&&a.options.infinite!==!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.removeClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled"),0===a.currentSlide?(a.$prevArrow.addClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-a.options.slidesToShow&&a.options.centerMode===!1?(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-1&&a.options.centerMode===!0&&(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")))},b.prototype.updateDots=function(){var a=this;null!==a.$dots&&(a.$dots.find("li").removeClass("slick-active").attr("aria-hidden","true"),a.$dots.find("li").eq(Math.floor(a.currentSlide/a.options.slidesToScroll)).addClass("slick-active").attr("aria-hidden","false"))},b.prototype.visibility=function(){var a=this;document[a.hidden]?(a.paused=!0,a.autoPlayClear()):(a.paused=!1,a.autoPlay())},a.fn.slick=function(){var g,a=this,c=arguments[0],d=Array.prototype.slice.call(arguments,1),e=a.length,f=0;for(f;e>f;f++)if("object"==typeof c||"undefined"==typeof c?a[f].slick=new b(a[f],c):g=a[f].slick[c].apply(a[f].slick,d),"undefined"!=typeof g)return g;return a}});
|
||||
@@ -1,116 +0,0 @@
|
||||
/* Slider */
|
||||
.slick-slider
|
||||
{
|
||||
position: relative;
|
||||
|
||||
display: block;
|
||||
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-touch-action: pan-y;
|
||||
touch-action: pan-y;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.slick-list
|
||||
{
|
||||
position: relative;
|
||||
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.slick-list:focus
|
||||
{
|
||||
outline: none;
|
||||
}
|
||||
.slick-list.dragging
|
||||
{
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
.slick-slider .slick-track,
|
||||
.slick-slider .slick-list
|
||||
{
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
-moz-transform: translate3d(0, 0, 0);
|
||||
-ms-transform: translate3d(0, 0, 0);
|
||||
-o-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
.slick-track
|
||||
{
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
display: block;
|
||||
}
|
||||
.slick-track:before,
|
||||
.slick-track:after
|
||||
{
|
||||
display: table;
|
||||
|
||||
content: '';
|
||||
}
|
||||
.slick-track:after
|
||||
{
|
||||
clear: both;
|
||||
}
|
||||
.slick-loading .slick-track
|
||||
{
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.slick-slide
|
||||
{
|
||||
display: none;
|
||||
float: left;
|
||||
|
||||
height: 100%;
|
||||
min-height: 1px;
|
||||
}
|
||||
[dir='rtl'] .slick-slide
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
.slick-slide img
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
.slick-slide.slick-loading img
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
.slick-slide.dragging img
|
||||
{
|
||||
pointer-events: none;
|
||||
}
|
||||
.slick-initialized .slick-slide
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
.slick-loading .slick-slide
|
||||
{
|
||||
visibility: hidden;
|
||||
}
|
||||
.slick-vertical .slick-slide
|
||||
{
|
||||
display: block;
|
||||
|
||||
height: auto;
|
||||
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
_ _ _ _
|
||||
___| (_) ___| | __ (_)___
|
||||
/ __| | |/ __| |/ / | / __|
|
||||
\__ \ | | (__| < _ | \__ \
|
||||
|___/_|_|\___|_|\_(_)/ |___/
|
||||
|__/
|
||||
|
||||
Version: 1.5.5
|
||||
Author: Ken Wheeler
|
||||
Website: http://kenwheeler.github.io
|
||||
Docs: http://kenwheeler.github.io/slick
|
||||
Repo: http://github.com/kenwheeler/slick
|
||||
Issues: http://github.com/kenwheeler/slick/issues
|
||||
|
||||
*/
|
||||
!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";var b=window.Slick||{};b=function(){function c(c,d){var f,g,h,e=this;if(e.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:a(c),appendDots:a(c),arrows:!0,asNavFor:null,prevArrow:'<button type="button" data-role="none" class="slick-prev" aria-label="previous">Previous</button>',nextArrow:'<button type="button" data-role="none" class="slick-next" aria-label="next">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(a,b){return'<button type="button" data-role="none">'+(b+1)+"</button>"},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0},e.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},a.extend(e,e.initials),e.activeBreakpoint=null,e.animType=null,e.animProp=null,e.breakpoints=[],e.breakpointSettings=[],e.cssTransitions=!1,e.hidden="hidden",e.paused=!1,e.positionProp=null,e.respondTo=null,e.rowCount=1,e.shouldClick=!0,e.$slider=a(c),e.$slidesCache=null,e.transformType=null,e.transitionType=null,e.visibilityChange="visibilitychange",e.windowWidth=0,e.windowTimer=null,f=a(c).data("slick")||{},e.options=a.extend({},e.defaults,f,d),e.currentSlide=e.options.initialSlide,e.originalSettings=e.options,g=e.options.responsive||null,g&&g.length>-1){e.respondTo=e.options.respondTo||"window";for(h in g)g.hasOwnProperty(h)&&(e.breakpoints.push(g[h].breakpoint),e.breakpointSettings[g[h].breakpoint]=g[h].settings);e.breakpoints.sort(function(a,b){return e.options.mobileFirst===!0?a-b:b-a})}"undefined"!=typeof document.mozHidden?(e.hidden="mozHidden",e.visibilityChange="mozvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(e.hidden="webkitHidden",e.visibilityChange="webkitvisibilitychange"),e.autoPlay=a.proxy(e.autoPlay,e),e.autoPlayClear=a.proxy(e.autoPlayClear,e),e.changeSlide=a.proxy(e.changeSlide,e),e.clickHandler=a.proxy(e.clickHandler,e),e.selectHandler=a.proxy(e.selectHandler,e),e.setPosition=a.proxy(e.setPosition,e),e.swipeHandler=a.proxy(e.swipeHandler,e),e.dragHandler=a.proxy(e.dragHandler,e),e.keyHandler=a.proxy(e.keyHandler,e),e.autoPlayIterator=a.proxy(e.autoPlayIterator,e),e.instanceUid=b++,e.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,e.init(!0),e.checkResponsive(!0)}var b=0;return c}(),b.prototype.addSlide=b.prototype.slickAdd=function(b,c,d){var e=this;if("boolean"==typeof c)d=c,c=null;else if(0>c||c>=e.slideCount)return!1;e.unload(),"number"==typeof c?0===c&&0===e.$slides.length?a(b).appendTo(e.$slideTrack):d?a(b).insertBefore(e.$slides.eq(c)):a(b).insertAfter(e.$slides.eq(c)):d===!0?a(b).prependTo(e.$slideTrack):a(b).appendTo(e.$slideTrack),e.$slides=e.$slideTrack.children(this.options.slide),e.$slideTrack.children(this.options.slide).detach(),e.$slideTrack.append(e.$slides),e.$slides.each(function(b,c){a(c).attr("data-slick-index",b)}),e.$slidesCache=e.$slides,e.reinit()},b.prototype.animateHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.animate({height:b},a.options.speed)}},b.prototype.animateSlide=function(b,c){var d={},e=this;e.animateHeight(),e.options.rtl===!0&&e.options.vertical===!1&&(b=-b),e.transformsEnabled===!1?e.options.vertical===!1?e.$slideTrack.animate({left:b},e.options.speed,e.options.easing,c):e.$slideTrack.animate({top:b},e.options.speed,e.options.easing,c):e.cssTransitions===!1?(e.options.rtl===!0&&(e.currentLeft=-e.currentLeft),a({animStart:e.currentLeft}).animate({animStart:b},{duration:e.options.speed,easing:e.options.easing,step:function(a){a=Math.ceil(a),e.options.vertical===!1?(d[e.animType]="translate("+a+"px, 0px)",e.$slideTrack.css(d)):(d[e.animType]="translate(0px,"+a+"px)",e.$slideTrack.css(d))},complete:function(){c&&c.call()}})):(e.applyTransition(),b=Math.ceil(b),d[e.animType]=e.options.vertical===!1?"translate3d("+b+"px, 0px, 0px)":"translate3d(0px,"+b+"px, 0px)",e.$slideTrack.css(d),c&&setTimeout(function(){e.disableTransition(),c.call()},e.options.speed))},b.prototype.asNavFor=function(b){var c=this,d=c.options.asNavFor;d&&null!==d&&(d=a(d).not(c.$slider)),null!==d&&"object"==typeof d&&Line truncated
|
||||
}else b.touchObject.startX!==b.touchObject.curX&&(b.slideHandler(b.currentSlide),b.touchObject={})},b.prototype.swipeHandler=function(a){var b=this;if(!(b.options.swipe===!1||"ontouchend"in document&&b.options.swipe===!1||b.options.draggable===!1&&-1!==a.type.indexOf("mouse")))switch(b.touchObject.fingerCount=a.originalEvent&&void 0!==a.originalEvent.touches?a.originalEvent.touches.length:1,b.touchObject.minSwipe=b.listWidth/b.options.touchThreshold,b.options.verticalSwiping===!0&&(b.touchObject.minSwipe=b.listHeight/b.options.touchThreshold),a.data.action){case"start":b.swipeStart(a);break;case"move":b.swipeMove(a);break;case"end":b.swipeEnd(a)}},b.prototype.swipeMove=function(a){var d,e,f,g,h,b=this;return h=void 0!==a.originalEvent?a.originalEvent.touches:null,!b.dragging||h&&1!==h.length?!1:(d=b.getLeft(b.currentSlide),b.touchObject.curX=void 0!==h?h[0].pageX:a.clientX,b.touchObject.curY=void 0!==h?h[0].pageY:a.clientY,b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curX-b.touchObject.startX,2))),b.options.verticalSwiping===!0&&(b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curY-b.touchObject.startY,2)))),e=b.swipeDirection(),"vertical"!==e?(void 0!==a.originalEvent&&b.touchObject.swipeLength>4&&a.preventDefault(),g=(b.options.rtl===!1?1:-1)*(b.touchObject.curX>b.touchObject.startX?1:-1),b.options.verticalSwiping===!0&&(g=b.touchObject.curY>b.touchObject.startY?1:-1),f=b.touchObject.swipeLength,b.touchObject.edgeHit=!1,b.options.infinite===!1&&(0===b.currentSlide&&"right"===e||b.currentSlide>=b.getDotCount()&&"left"===e)&&(f=b.touchObject.swipeLength*b.options.edgeFriction,b.touchObject.edgeHit=!0),b.swipeLeft=b.options.vertical===!1?d+f*g:d+f*(b.$list.height()/b.listWidth)*g,b.options.verticalSwiping===!0&&(b.swipeLeft=d+f*g),b.options.fade===!0||b.options.touchMove===!1?!1:b.animating===!0?(b.swipeLeft=null,!1):(b.setCSS(b.swipeLeft),void 0)):void 0)},b.prototype.swipeStart=function(a){var c,b=this;return 1!==b.touchObject.fingerCount||b.slideCount<=b.options.slidesToShow?(b.touchObject={},!1):(void 0!==a.originalEvent&&void 0!==a.originalEvent.touches&&(c=a.originalEvent.touches[0]),b.touchObject.startX=b.touchObject.curX=void 0!==c?c.pageX:a.clientX,b.touchObject.startY=b.touchObject.curY=void 0!==c?c.pageY:a.clientY,b.dragging=!0,void 0)},b.prototype.unfilterSlides=b.prototype.slickUnfilter=function(){var a=this;null!==a.$slidesCache&&(a.unload(),a.$slideTrack.children(this.options.slide).detach(),a.$slidesCache.appendTo(a.$slideTrack),a.reinit())},b.prototype.unload=function(){var b=this;a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&"object"!=typeof b.options.prevArrow&&b.$prevArrow.remove(),b.$nextArrow&&"object"!=typeof b.options.nextArrow&&b.$nextArrow.remove(),b.$slides.removeClass("slick-slide slick-active slick-visible").attr("aria-hidden","true").css("width","")},b.prototype.unslick=function(a){var b=this;b.$slider.trigger("unslick",[b,a]),b.destroy()},b.prototype.updateArrows=function(){var b,a=this;b=Math.floor(a.options.slidesToShow/2),a.options.arrows===!0&&a.options.infinite!==!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.removeClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled"),0===a.currentSlide?(a.$prevArrow.addClass("slick-disabled"),a.$nextArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-a.options.slidesToShow&&a.options.centerMode===!1?(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")):a.currentSlide>=a.slideCount-1&&a.options.centerMode===!0&&(a.$nextArrow.addClass("slick-disabled"),a.$prevArrow.removeClass("slick-disabled")))},b.prototype.updateDots=function(){var a=this;null!==a.$dots&&(a.$dots.find("li").removeClass("slick-active").attr("aria-hidden","true"),a.$dots.find("li").eq(Math.floor(a.currentSlide/a.options.slidesToScroll)).addClass("slick-active").attr("aria-hidden","false"))},b.prototype.visibility=function(){var a=this;document[a.hidden]?(a.paused=!0,a.autoPlayClear()):a.options.autoplay===!0&&(a.paused=!1,a.autoPlay())},a.fn.slick=function(){var g,a=this,c=arguments[0],d=Array.prototype.slice.call(arguments,1),e=a.length,f=0;for(f;e>f;f++)if("object"==typeof c||"undefined"==typeof c?a[f].slick=new b(a[f],c):g=a[f].slick[c].apply(a[f].slick,d),"undefined"!=typeof g)return g;return a}});
|
||||
File renamed without changes.
+3
@@ -113,4 +113,7 @@
|
||||
height: auto;
|
||||
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.slick-arrow.slick-hidden {
|
||||
display: none;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
_ _ _ _
|
||||
___| (_) ___| | __ (_)___
|
||||
/ __| | |/ __| |/ / | / __|
|
||||
\__ \ | | (__| < _ | \__ \
|
||||
|___/_|_|\___|_|\_(_)/ |___/
|
||||
|__/
|
||||
|
||||
Version: 1.5.8
|
||||
Author: Ken Wheeler
|
||||
Website: http://kenwheeler.github.io
|
||||
Docs: http://kenwheeler.github.io/slick
|
||||
Repo: http://github.com/kenwheeler/slick
|
||||
Issues: http://github.com/kenwheeler/slick/issues
|
||||
|
||||
*/
|
||||
!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";var b=window.Slick||{};b=function(){function c(c,d){var f,e=this;e.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:a(c),appendDots:a(c),arrows:!0,asNavFor:null,prevArrow:'<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',nextArrow:'<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(a,b){return'<button type="button" data-role="none" role="button" aria-required="false" tabindex="0">'+(b+1)+"</button>"},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},e.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},a.extend(e,e.initials),e.activeBreakpoint=null,e.animType=null,e.animProp=null,e.breakpoints=[],e.breakpointSettings=[],e.cssTransitions=!1,e.hidden="hidden",e.paused=!1,e.positionProp=null,e.respondTo=null,e.rowCount=1,e.shouldClick=!0,e.$slider=a(c),e.$slidesCache=null,e.transformType=null,e.transitionType=null,e.visibilityChange="visibilitychange",e.windowWidth=0,e.windowTimer=null,f=a(c).data("slick")||{},e.options=a.extend({},e.defaults,f,d),e.currentSlide=e.options.initialSlide,e.originalSettings=e.options,"undefined"!=typeof document.mozHidden?(e.hidden="mozHidden",e.visibilityChange="mozvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(e.hidden="webkitHidden",e.visibilityChange="webkitvisibilitychange"),e.autoPlay=a.proxy(e.autoPlay,e),e.autoPlayClear=a.proxy(e.autoPlayClear,e),e.changeSlide=a.proxy(e.changeSlide,e),e.clickHandler=a.proxy(e.clickHandler,e),e.selectHandler=a.proxy(e.selectHandler,e),e.setPosition=a.proxy(e.setPosition,e),e.swipeHandler=a.proxy(e.swipeHandler,e),e.dragHandler=a.proxy(e.dragHandler,e),e.keyHandler=a.proxy(e.keyHandler,e),e.autoPlayIterator=a.proxy(e.autoPlayIterator,e),e.instanceUid=b++,e.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,e.registerBreakpoints(),e.init(!0),e.checkResponsive(!0)}var b=0;return c}(),b.prototype.addSlide=b.prototype.slickAdd=function(b,c,d){var e=this;if("boolean"==typeof c)d=c,c=null;else if(0>c||c>=e.slideCount)return!1;e.unload(),"number"==typeof c?0===c&&0===e.$slides.length?a(b).appendTo(e.$slideTrack):d?a(b).insertBefore(e.$slides.eq(c)):a(b).insertAfter(e.$slides.eq(c)):d===!0?a(b).prependTo(e.$slideTrack):a(b).appendTo(e.$slideTrack),e.$slides=e.$slideTrack.children(this.options.slide),e.$slideTrack.children(this.options.slide).detach(),e.$slideTrack.append(e.$slides),e.$slides.each(function(b,c){a(c).attr("data-slick-index",b)}),e.$slidesCache=e.$slides,e.reinit()},b.prototype.animateHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.animate({height:b},a.options.speed)}},b.prototype.animateSlide=function(b,c){var d={},e=this;e.animateHeight(),e.options.rtl===!0&&e.options.vertical===!1&&(b=-b),e.transformsEnabled===!1?e.options.vertical===!1?e.$slideTrack.animate({left:b},e.options.speed,e.options.easing,c):e.$slideTrack.animate({top:b},e.options.speed,e.options.easing,c):e.cssTransitions===!1?(e.options.rtl===!0&&(e.currentLeft=-e.currentLeft),a({animStart:e.currentLeft}).animate({animStart:b},{duration:e.options.speed,easing:e.options.easing,step:function(a){a=Math.ceil(a),e.options.vertical===!1?(d[e.animType]="translate("+a+"px, 0px)",e.$slideTrack.css(d)):(d[e.animType]="translate(0px,"+a+"px)",e.$slideTrack.css(d))},complete:function(){c&&c.call()}})):(e.applyTransition(),b=Math.ceil(b),d[e.animType]=e.options.vertical===!1?"translate3d("+b+"px, 0px, 0px)":"translate3d(0px,"+b+"px, 0px)",e.$slideTrack.css(d),c&&setTimeout(function(){e.disableTransition(),c.call()},e.options.speed))},b.prototype.asNavFor=function(b){var c=this,d=c.options.asNavFor;d&&null!==d&&(d=a(d).not(c.$slider)),null!==d&&"object"==typeof d&&d.each(function(){var c=a(this).slick("getSlick");c.unslicked||c.slideHandler(b,!0)})},b.prototype.applyTransition=function(a){var b=this,c={};c[b.transitiLine truncated
|
||||
})):i.postSlide(e),i.animateHeight(),void 0):(c!==!0?i.animateSlide(h,function(){i.postSlide(e)}):i.postSlide(e),void 0)))},b.prototype.startLoad=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.hide(),a.$nextArrow.hide()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.hide(),a.$slider.addClass("slick-loading")},b.prototype.swipeDirection=function(){var a,b,c,d,e=this;return a=e.touchObject.startX-e.touchObject.curX,b=e.touchObject.startY-e.touchObject.curY,c=Math.atan2(b,a),d=Math.round(180*c/Math.PI),0>d&&(d=360-Math.abs(d)),45>=d&&d>=0?e.options.rtl===!1?"left":"right":360>=d&&d>=315?e.options.rtl===!1?"left":"right":d>=135&&225>=d?e.options.rtl===!1?"right":"left":e.options.verticalSwiping===!0?d>=35&&135>=d?"left":"right":"vertical"},b.prototype.swipeEnd=function(){var c,b=this;if(b.dragging=!1,b.shouldClick=b.touchObject.swipeLength>10?!1:!0,void 0===b.touchObject.curX)return!1;if(b.touchObject.edgeHit===!0&&b.$slider.trigger("edge",[b,b.swipeDirection()]),b.touchObject.swipeLength>=b.touchObject.minSwipe)switch(b.swipeDirection()){case"left":c=b.options.swipeToSlide?b.checkNavigable(b.currentSlide+b.getSlideCount()):b.currentSlide+b.getSlideCount(),b.slideHandler(c),b.currentDirection=0,b.touchObject={},b.$slider.trigger("swipe",[b,"left"]);break;case"right":c=b.options.swipeToSlide?b.checkNavigable(b.currentSlide-b.getSlideCount()):b.currentSlide-b.getSlideCount(),b.slideHandler(c),b.currentDirection=1,b.touchObject={},b.$slider.trigger("swipe",[b,"right"])}else b.touchObject.startX!==b.touchObject.curX&&(b.slideHandler(b.currentSlide),b.touchObject={})},b.prototype.swipeHandler=function(a){var b=this;if(!(b.options.swipe===!1||"ontouchend"in document&&b.options.swipe===!1||b.options.draggable===!1&&-1!==a.type.indexOf("mouse")))switch(b.touchObject.fingerCount=a.originalEvent&&void 0!==a.originalEvent.touches?a.originalEvent.touches.length:1,b.touchObject.minSwipe=b.listWidth/b.options.touchThreshold,b.options.verticalSwiping===!0&&(b.touchObject.minSwipe=b.listHeight/b.options.touchThreshold),a.data.action){case"start":b.swipeStart(a);break;case"move":b.swipeMove(a);break;case"end":b.swipeEnd(a)}},b.prototype.swipeMove=function(a){var d,e,f,g,h,b=this;return h=void 0!==a.originalEvent?a.originalEvent.touches:null,!b.dragging||h&&1!==h.length?!1:(d=b.getLeft(b.currentSlide),b.touchObject.curX=void 0!==h?h[0].pageX:a.clientX,b.touchObject.curY=void 0!==h?h[0].pageY:a.clientY,b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curX-b.touchObject.startX,2))),b.options.verticalSwiping===!0&&(b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curY-b.touchObject.startY,2)))),e=b.swipeDirection(),"vertical"!==e?(void 0!==a.originalEvent&&b.touchObject.swipeLength>4&&a.preventDefault(),g=(b.options.rtl===!1?1:-1)*(b.touchObject.curX>b.touchObject.startX?1:-1),b.options.verticalSwiping===!0&&(g=b.touchObject.curY>b.touchObject.startY?1:-1),f=b.touchObject.swipeLength,b.touchObject.edgeHit=!1,b.options.infinite===!1&&(0===b.currentSlide&&"right"===e||b.currentSlide>=b.getDotCount()&&"left"===e)&&(f=b.touchObject.swipeLength*b.options.edgeFriction,b.touchObject.edgeHit=!0),b.swipeLeft=b.options.vertical===!1?d+f*g:d+f*(b.$list.height()/b.listWidth)*g,b.options.verticalSwiping===!0&&(b.swipeLeft=d+f*g),b.options.fade===!0||b.options.touchMove===!1?!1:b.animating===!0?(b.swipeLeft=null,!1):(b.setCSS(b.swipeLeft),void 0)):void 0)},b.prototype.swipeStart=function(a){var c,b=this;return 1!==b.touchObject.fingerCount||b.slideCount<=b.options.slidesToShow?(b.touchObject={},!1):(void 0!==a.originalEvent&&void 0!==a.originalEvent.touches&&(c=a.originalEvent.touches[0]),b.touchObject.startX=b.touchObject.curX=void 0!==c?c.pageX:a.clientX,b.touchObject.startY=b.touchObject.curY=void 0!==c?c.pageY:a.clientY,b.dragging=!0,void 0)},b.prototype.unfilterSlides=b.prototype.slickUnfilter=function(){var a=this;null!==a.$slidesCache&&(a.unload(),a.$slideTrack.children(this.options.slide).detach(),a.$slidesCache.appendTo(a.$slideTrack),a.reinit())},b.prototype.unload=function(){var b=this;a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&b.htmlExpr.test(b.options.prevArrow)&&b.$prevArrow.remove(),b.$nextArrow&&b.htmlExpr.test(b.options.nextArrow)&&b.$nextArrow.remove(),b.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")},b.prototype.unslick=function(a){var b=this;b.$slider.trigger("unslick",[b,a]),b.destroy()},b.prototype.updateArrows=function(){var b,a=this;b=Math.floor(a.options.slidesToShow/2),a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&!a.options.infinite&&(a.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),a.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===a.currentSlide?(a.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),a.$nextArrow.removeClass(Line truncated
|
||||
@@ -1,90 +0,0 @@
|
||||
@charset 'UTF-8';
|
||||
|
||||
/* Dots */
|
||||
.slick-slider
|
||||
{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.slick-dots
|
||||
{
|
||||
position: absolute;
|
||||
bottom: -45px;
|
||||
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
|
||||
list-style: none;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
.slick-dots li
|
||||
{
|
||||
position: relative;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 5px;
|
||||
padding: 0;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
.slick-dots li button
|
||||
{
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
|
||||
display: block;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 5px;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
color: transparent;
|
||||
border: 0;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
.slick-dots li button:hover,
|
||||
.slick-dots li button:focus
|
||||
{
|
||||
outline: none;
|
||||
}
|
||||
.slick-dots li button:hover:before,
|
||||
.slick-dots li button:focus:before
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
.slick-dots li button:before
|
||||
{
|
||||
font-family: 'slick';
|
||||
font-size: 6px;
|
||||
line-height: 20px;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
content: '•';
|
||||
text-align: center;
|
||||
|
||||
opacity: .25;
|
||||
color: black;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.slick-dots li.slick-active button:before
|
||||
{
|
||||
opacity: .75;
|
||||
color: black;
|
||||
}
|
||||
+8
-2
@@ -1,5 +1,5 @@
|
||||
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
|
||||
xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:c="urn:import:com.sap.sailing.gwt.common.client.controls.tabbar">
|
||||
xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:c="urn:import:com.sap.sailing.gwt.common.client.controls.tabbar" xmlns:b="urn:import:com.sap.sse.gwt.client.controls.busyindicator">
|
||||
<ui:with field="res"
|
||||
type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:style>
|
||||
@@ -35,6 +35,10 @@
|
||||
float: right;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.busy {
|
||||
width: 32px;
|
||||
margin: 2em auto 10em;
|
||||
}
|
||||
</ui:style>
|
||||
<g:FlowPanel>
|
||||
<g:HTMLPanel addStyleNames="{style.header}">
|
||||
@@ -54,6 +58,8 @@
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
<g:SimplePanel ui:field="tabContentPanelUi"
|
||||
addStyleNames="{style.content}" />
|
||||
addStyleNames="{style.content}">
|
||||
<b:SimpleBusyIndicator addStyleNames="{style.busy}" busy="true" />
|
||||
</g:SimplePanel>
|
||||
</g:FlowPanel>
|
||||
</ui:UiBinder>
|
||||
+1
-1
@@ -45,7 +45,7 @@ public interface TextMessages extends Messages {
|
||||
String sapSailing();
|
||||
String search();
|
||||
String startSimulator();
|
||||
|
||||
String countdownStartingInDays();
|
||||
String countdownDays();
|
||||
String countdownHours();
|
||||
String countdownMinutes();
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ overview=Overview
|
||||
sapSailing=SAP Sailing
|
||||
search=Search
|
||||
startSimulator=Start Simulator
|
||||
|
||||
countdownStartingInDays=Days
|
||||
countdownDays=Days
|
||||
countdownHours=Hrs
|
||||
countdownMinutes=Min
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ overview=Übersicht
|
||||
sapSailing=SAP Sailing
|
||||
search=Suche
|
||||
startSimulator=Simulator starten
|
||||
|
||||
countdownStartingInDays=Tagen
|
||||
countdownDays=Tage
|
||||
countdownHours=Std.
|
||||
countdownMinutes=Min.
|
||||
|
||||
+184
-183
@@ -1,183 +1,184 @@
|
||||
socialFooterShare=Share this on
|
||||
home=主页
|
||||
aboutUs=关于我们
|
||||
contact=联络
|
||||
sponsoring=赞助商
|
||||
solutions=解决方案
|
||||
events=比赛
|
||||
german=德语
|
||||
english=英语
|
||||
officalEventWebsite=官方活动网站
|
||||
leg=站
|
||||
races=赛事
|
||||
moreInfo=更多信息
|
||||
viewAnalysis=观看分析
|
||||
overallLeaderboard=总排行榜
|
||||
pleaseEnterASearchTerm=请输入搜索词
|
||||
pleaseTryAgain=请再试一次
|
||||
reloadPage=重新载入页面
|
||||
errorMessageLoadingData=加载该页的数据时出错
|
||||
errorMessageNoSuchLeaderboard=无法利用这词寻找排行榜
|
||||
raceNotScheduled=没有确认时间
|
||||
regattaDetails=帆船赛细节
|
||||
regatta=帆船赛
|
||||
competitorsAnalytics=队伍分析
|
||||
chooseChart=选择图标类型
|
||||
series=系列
|
||||
regattaLeaderboards=帆船赛排行榜
|
||||
features=功能
|
||||
releaseNotes=软件更新发布
|
||||
whatsNew=最新信息
|
||||
overview=概览
|
||||
sapSailing=SAP帆船
|
||||
search=搜索
|
||||
startSimulator=启动模拟器
|
||||
live=实时
|
||||
finished=结束
|
||||
watchNow=马上观看
|
||||
lastUpdate=最后更新
|
||||
leaderboard=排行榜
|
||||
eventHeaderMedia=媒体
|
||||
eventHeaderOverview=概览
|
||||
eventHeaderRaces=赛程
|
||||
eventHeaderRegattas=帆船赛
|
||||
seriesHeaderOverview=关于比赛系列
|
||||
seriesHeaderUpcoming=未来赛事
|
||||
seriesHeaderRecent=最近赛事
|
||||
seriesHeaderLeaderboard=排行榜
|
||||
eventsOverviewRecentEvents=赛事
|
||||
eventsOverviewRecentCountries=国家
|
||||
eventsOverviewRecentSailors=运动员
|
||||
eventsOverviewRecentTrackedRaces=赛事(含比赛分析)
|
||||
eventResultsHeadline=比赛结果
|
||||
eventResultsBoatClassesDropDown=所有帆船级别
|
||||
eventOverviewMoreEvents=更多赛事
|
||||
eventOverviewRecentEvents=最近赛事
|
||||
eventOverviewUpcomingDate=日期
|
||||
eventOverviewUpcomingEvent=赛事
|
||||
eventOverviewUpcomingLocation=地点
|
||||
eventOverviewUpcomingSchedule=未来赛程
|
||||
eventOverviewUpcomingSeries=系列
|
||||
eventOverviewUpcomingTeaser=更多赛事即将公布
|
||||
eventQuickfinderTitle=赛事快速查找
|
||||
eventRegattaHeaderLeaderboard=排行榜
|
||||
eventRegattaHeaderRaceRaces=赛事
|
||||
eventRegattaListAllBoatClasses=所有帆船级别
|
||||
eventRegattaLeaderboardCompetitor=比赛队伍
|
||||
eventRegattaLeaderboardExtendLeaderboard=详细排行榜
|
||||
eventRegattaLeaderboardFinishedMessage=没有更多比赛
|
||||
eventRegattaLeaderboardLastScoreUpdate=最后积分更新
|
||||
eventRegattaLeaderboardName=队伍名称
|
||||
eventRegattaLeaderboardRegattaRank=帆船赛排名
|
||||
eventRegattaLeaderboardTotalPoints=总积分
|
||||
eventRegattaRaceWatch=实时观看
|
||||
eventRegattaRaceAnalyse=赛事分析
|
||||
eventRegattaRaceNotTracked=不含比赛分析
|
||||
mainEventShowAll=显示所有赛事
|
||||
mainEventTitle=最新帆船赛事
|
||||
mainMediaSubtitle=
|
||||
mainMediaTitle=照片
|
||||
mainMediaVideosSubtitle=
|
||||
mainMediaVideosTitle=最新视频
|
||||
mainSponsorsReadMore=阅读更多
|
||||
mediaTeaserPhotosTitle=照片
|
||||
mediaTeaserVideosTitle=视频
|
||||
regattaCompetitors=比赛队伍\竞争对手
|
||||
regattaRaces=赛事
|
||||
regattaTracked=Tracked
|
||||
regattaRegattaStarts=帆船比赛即将开始
|
||||
regattaPts=积分
|
||||
regattaCourse=帆船赛程
|
||||
regattaArea=地点
|
||||
regattaFinishedAt=结束时间为
|
||||
regattaScheduledAt=开始时间为
|
||||
regattaStartedAt=开始时间为
|
||||
regattasResultsTitle=比赛结果
|
||||
searchResultHeaderButton=搜寻
|
||||
searchResultHeaderLabel=您的搜寻
|
||||
searchResultsFound=搜寻结果
|
||||
searchResultHeaderPlaceholder=输入您的搜寻关键词
|
||||
searchResultMore=更多
|
||||
searchResultSearch=搜寻
|
||||
searchResultSearchAgain=重新搜寻
|
||||
searchResultSortLabel=排序方式
|
||||
searchResultSortNewest=最近
|
||||
searchResultSortOldest=最旧
|
||||
searchResultSortRelevance=相关性
|
||||
solutionsSAPNav=SAP帆船比赛分析
|
||||
solutionsSAPHeadline=SAP帆船比赛分析
|
||||
countdownDays=Days
|
||||
countdownHours=Hrs
|
||||
countdownMinutes=Min
|
||||
countdownSeconds=Sec
|
||||
countdownDay=Day
|
||||
countdownHour=Hour
|
||||
countdownMinute=Min
|
||||
countdownSecond=Sec
|
||||
boxNewsUpdateMoreLink=Report news
|
||||
boxNewsUpdateTitle=News Update
|
||||
boxUpcomingRacesCountdownStarted1=Started
|
||||
boxUpcomingRacesCountdownStarted2=hrs and
|
||||
boxUpcomingRacesCountdownStarted3=minutes ago
|
||||
boxUpcomingRacesCountdownStarting1=Starting in
|
||||
boxUpcomingRacesCountdownStarting2=hrs and
|
||||
boxUpcomingRacesCountdownStarting3=minutes
|
||||
boxUpcomingRacesMoreLink=Event Schedule
|
||||
boxUpcomingRacesTitle=Upcoming Races Today
|
||||
boxWeather=Weather
|
||||
boxWeatherUnit=KTS
|
||||
defaultTitle=SAP帆船
|
||||
seriesOverviewHeaderRecent=Latest Series Events
|
||||
seriesOverviewReadMore=More
|
||||
eventRegattaRaceFinished=Finished at:
|
||||
eventRegattaRaceStarted=Started at:
|
||||
eventRegattaRaceScheduled=Scheduled for:
|
||||
eventRegattaRaceRace=Race
|
||||
eventRegattaRaceWind=Wind Strength:
|
||||
eventRegattaRaceWinner=Winner
|
||||
eventRegattaRaceLeader=Leader
|
||||
eventRegattaRacesLegendGps=Tracking
|
||||
eventRegattaRacesLegendWind=Wind Data
|
||||
eventRegattaRacesLegendVideo=Video
|
||||
eventRegattaRacesLegendAudio=Audio
|
||||
eventSponsorsTitle=Event Sponsorships
|
||||
footerJobs=Jobs
|
||||
footerCopyright=\u00A9 2015 SAP帆船
|
||||
footerLanguage=SAP Sailing offered in
|
||||
footerLegal=Legal Disclosure
|
||||
footerPrivacy=Privacy
|
||||
footerFeedback=Feedback
|
||||
headerEvents=比赛
|
||||
headerHome=主页
|
||||
headerLogo=SAP帆船
|
||||
headerSearch=搜索
|
||||
headerSearchPlaceholder=搜索
|
||||
headerSolutions=Solutions
|
||||
headerSponsoring=Sponsoring
|
||||
latestRaceResultsHeadline=Latest Official Race Results
|
||||
latestRaceResultsIsNew=New
|
||||
latestRaceResultsIsUpdated=Updated
|
||||
latestRaceResultsRaceCountLabel=Result after
|
||||
latestRaceResultsRaceCountUnit=races
|
||||
latestRaceResultsRefresh=refresh
|
||||
leaderboardQuickAccessLabel=Leaderboard Quick Access
|
||||
searchResultCount=About 2,450 results where found for 'Schnitzel'
|
||||
sharingEmail=Send an email
|
||||
sharingFacebook=Share on Facebook
|
||||
sharingTwitter=Tweet about it
|
||||
socialFooterTitle=Recommend SAP Sailing Analytics
|
||||
solutionsSAPText1=By delivering real time analytics around race rankings, speeds, maneuvers, bearings etc., SAP is helping to simplify and demystify the complex sport of sailing.
|
||||
solutionsSAPText2=SAP Sailing Analytics provide insights and transparency to the world of sailing by utilizing Cloud and In-Memory Technology, processing GPS and wind measurement data in real time and visualizing contents in various frontends accessible from anywhere.
|
||||
solutionsRaceNav=Race Committee App
|
||||
solutionsRaceHeadline=Race Committee App
|
||||
solutionsRaceText=The SAP Race Committee App delivers greater efficiency and control to race organizers by automating and simplifying their manual tasks and communication during running sailing regattas. The Race Committee App helps simplify the operation of running and managing race events to help race committees operate smarter.
|
||||
solutionsPostNav=Post-Race Analytics
|
||||
solutionsPostHeadline=Post-Race Analytics
|
||||
solutionsPostText=Access to data collected at sailing events gives sailors the opportunity to assess and analyse their performances to help develop strategies and sail better.<br> SAP Business Analytics solutions provide sailors, coaches, fans and media with tools to browse and analyse historical data across many regattas and races. SAP HANA allows them to learn about performance patterns, tendencies and sailor profiles in a simple, fast and efficient way in order to optimize their own performance and develop successful strategies for future regattas.
|
||||
solutionsTrainingNav=Training Diary
|
||||
solutionsTrainingHeadline=SAP Sail Better \u2013 STG Training Diary
|
||||
solutionsTrainingText=The STG Training Diary supports the daily documentation and analysis of an athlete\u2019s physical condition and training efforts in the areas of water training, physical training, boat work, mental, theory as well as other activities like education or travel.
|
||||
solutionsSimulatorNav=Strategy Simulator
|
||||
solutionsSimulatorHeadline=Strategy Simulator
|
||||
solutionsSimulatorText=Choosing the right strategy can provide great competitive advantage during a race. The Strategy Simulator simplifies determining the best sailing strategy for various wind conditions and water currents. Since wind and current can be changed in the simulation right away, the robustness of a strategy can be easily evaluated even for uncertain weather conditions.
|
||||
|
||||
socialFooterShare=Share this on
|
||||
home=主页
|
||||
aboutUs=关于我们
|
||||
contact=联络
|
||||
sponsoring=赞助商
|
||||
solutions=解决方案
|
||||
events=比赛
|
||||
german=德语
|
||||
english=英语
|
||||
officalEventWebsite=官方活动网站
|
||||
leg=站
|
||||
races=赛事
|
||||
moreInfo=更多信息
|
||||
viewAnalysis=观看分析
|
||||
overallLeaderboard=总排行榜
|
||||
pleaseEnterASearchTerm=请输入搜索词
|
||||
pleaseTryAgain=请再试一次
|
||||
reloadPage=重新载入页面
|
||||
errorMessageLoadingData=加载该页的数据时出错
|
||||
errorMessageNoSuchLeaderboard=无法利用这词寻找排行榜
|
||||
raceNotScheduled=没有确认时间
|
||||
regattaDetails=帆船赛细节
|
||||
regatta=帆船赛
|
||||
competitorsAnalytics=队伍分析
|
||||
chooseChart=选择图标类型
|
||||
series=系列
|
||||
regattaLeaderboards=帆船赛排行榜
|
||||
features=功能
|
||||
releaseNotes=软件更新发布
|
||||
whatsNew=最新信息
|
||||
overview=概览
|
||||
sapSailing=SAP帆船
|
||||
search=搜索
|
||||
startSimulator=启动模拟器
|
||||
live=实时
|
||||
finished=结束
|
||||
watchNow=马上观看
|
||||
lastUpdate=最后更新
|
||||
leaderboard=排行榜
|
||||
eventHeaderMedia=媒体
|
||||
eventHeaderOverview=概览
|
||||
eventHeaderRaces=赛程
|
||||
eventHeaderRegattas=帆船赛
|
||||
seriesHeaderOverview=关于比赛系列
|
||||
seriesHeaderUpcoming=未来赛事
|
||||
seriesHeaderRecent=最近赛事
|
||||
seriesHeaderLeaderboard=排行榜
|
||||
eventsOverviewRecentEvents=赛事
|
||||
eventsOverviewRecentCountries=国家
|
||||
eventsOverviewRecentSailors=运动员
|
||||
eventsOverviewRecentTrackedRaces=赛事(含比赛分析)
|
||||
eventResultsHeadline=比赛结果
|
||||
eventResultsBoatClassesDropDown=所有帆船级别
|
||||
eventOverviewMoreEvents=更多赛事
|
||||
eventOverviewRecentEvents=最近赛事
|
||||
eventOverviewUpcomingDate=日期
|
||||
eventOverviewUpcomingEvent=赛事
|
||||
eventOverviewUpcomingLocation=地点
|
||||
eventOverviewUpcomingSchedule=未来赛程
|
||||
eventOverviewUpcomingSeries=系列
|
||||
eventOverviewUpcomingTeaser=更多赛事即将公布
|
||||
eventQuickfinderTitle=赛事快速查找
|
||||
eventRegattaHeaderLeaderboard=排行榜
|
||||
eventRegattaHeaderRaceRaces=赛事
|
||||
eventRegattaListAllBoatClasses=所有帆船级别
|
||||
eventRegattaLeaderboardCompetitor=比赛队伍
|
||||
eventRegattaLeaderboardExtendLeaderboard=详细排行榜
|
||||
eventRegattaLeaderboardFinishedMessage=没有更多比赛
|
||||
eventRegattaLeaderboardLastScoreUpdate=最后积分更新
|
||||
eventRegattaLeaderboardName=队伍名称
|
||||
eventRegattaLeaderboardRegattaRank=帆船赛排名
|
||||
eventRegattaLeaderboardTotalPoints=总积分
|
||||
eventRegattaRaceWatch=实时观看
|
||||
eventRegattaRaceAnalyse=赛事分析
|
||||
eventRegattaRaceNotTracked=不含比赛分析
|
||||
mainEventShowAll=显示所有赛事
|
||||
mainEventTitle=最新帆船赛事
|
||||
mainMediaSubtitle=
|
||||
mainMediaTitle=照片
|
||||
mainMediaVideosSubtitle=
|
||||
mainMediaVideosTitle=最新视频
|
||||
mainSponsorsReadMore=阅读更多
|
||||
mediaTeaserPhotosTitle=照片
|
||||
mediaTeaserVideosTitle=视频
|
||||
regattaCompetitors=比赛队伍\竞争对手
|
||||
regattaRaces=赛事
|
||||
regattaTracked=Tracked
|
||||
regattaRegattaStarts=帆船比赛即将开始
|
||||
regattaPts=积分
|
||||
regattaCourse=帆船赛程
|
||||
regattaArea=地点
|
||||
regattaFinishedAt=结束时间为
|
||||
regattaScheduledAt=开始时间为
|
||||
regattaStartedAt=开始时间为
|
||||
regattasResultsTitle=比赛结果
|
||||
searchResultHeaderButton=搜寻
|
||||
searchResultHeaderLabel=您的搜寻
|
||||
searchResultsFound=搜寻结果
|
||||
searchResultHeaderPlaceholder=输入您的搜寻关键词
|
||||
searchResultMore=更多
|
||||
searchResultSearch=搜寻
|
||||
searchResultSearchAgain=重新搜寻
|
||||
searchResultSortLabel=排序方式
|
||||
searchResultSortNewest=最近
|
||||
searchResultSortOldest=最旧
|
||||
searchResultSortRelevance=相关性
|
||||
solutionsSAPNav=SAP帆船比赛分析
|
||||
solutionsSAPHeadline=SAP帆船比赛分析
|
||||
countdownStartingInDays=Days
|
||||
countdownDays=Days
|
||||
countdownHours=Hrs
|
||||
countdownMinutes=Min
|
||||
countdownSeconds=Sec
|
||||
countdownDay=Day
|
||||
countdownHour=Hour
|
||||
countdownMinute=Min
|
||||
countdownSecond=Sec
|
||||
boxNewsUpdateMoreLink=Report news
|
||||
boxNewsUpdateTitle=News Update
|
||||
boxUpcomingRacesCountdownStarted1=Started
|
||||
boxUpcomingRacesCountdownStarted2=hrs and
|
||||
boxUpcomingRacesCountdownStarted3=minutes ago
|
||||
boxUpcomingRacesCountdownStarting1=Starting in
|
||||
boxUpcomingRacesCountdownStarting2=hrs and
|
||||
boxUpcomingRacesCountdownStarting3=minutes
|
||||
boxUpcomingRacesMoreLink=Event Schedule
|
||||
boxUpcomingRacesTitle=Upcoming Races Today
|
||||
boxWeather=Weather
|
||||
boxWeatherUnit=KTS
|
||||
defaultTitle=SAP帆船
|
||||
seriesOverviewHeaderRecent=Latest Series Events
|
||||
seriesOverviewReadMore=More
|
||||
eventRegattaRaceFinished=Finished at:
|
||||
eventRegattaRaceStarted=Started at:
|
||||
eventRegattaRaceScheduled=Scheduled for:
|
||||
eventRegattaRaceRace=Race
|
||||
eventRegattaRaceWind=Wind Strength:
|
||||
eventRegattaRaceWinner=Winner
|
||||
eventRegattaRaceLeader=Leader
|
||||
eventRegattaRacesLegendGps=Tracking
|
||||
eventRegattaRacesLegendWind=Wind Data
|
||||
eventRegattaRacesLegendVideo=Video
|
||||
eventRegattaRacesLegendAudio=Audio
|
||||
eventSponsorsTitle=Event Sponsorships
|
||||
footerJobs=Jobs
|
||||
footerCopyright=\u00A9 2015 SAP帆船
|
||||
footerLanguage=SAP Sailing offered in
|
||||
footerLegal=Legal Disclosure
|
||||
footerPrivacy=Privacy
|
||||
footerFeedback=Feedback
|
||||
headerEvents=比赛
|
||||
headerHome=主页
|
||||
headerLogo=SAP帆船
|
||||
headerSearch=搜索
|
||||
headerSearchPlaceholder=搜索
|
||||
headerSolutions=Solutions
|
||||
headerSponsoring=Sponsoring
|
||||
latestRaceResultsHeadline=Latest Official Race Results
|
||||
latestRaceResultsIsNew=New
|
||||
latestRaceResultsIsUpdated=Updated
|
||||
latestRaceResultsRaceCountLabel=Result after
|
||||
latestRaceResultsRaceCountUnit=races
|
||||
latestRaceResultsRefresh=refresh
|
||||
leaderboardQuickAccessLabel=Leaderboard Quick Access
|
||||
searchResultCount=About 2,450 results where found for 'Schnitzel'
|
||||
sharingEmail=Send an email
|
||||
sharingFacebook=Share on Facebook
|
||||
sharingTwitter=Tweet about it
|
||||
socialFooterTitle=Recommend SAP Sailing Analytics
|
||||
solutionsSAPText1=By delivering real time analytics around race rankings, speeds, maneuvers, bearings etc., SAP is helping to simplify and demystify the complex sport of sailing.
|
||||
solutionsSAPText2=SAP Sailing Analytics provide insights and transparency to the world of sailing by utilizing Cloud and In-Memory Technology, processing GPS and wind measurement data in real time and visualizing contents in various frontends accessible from anywhere.
|
||||
solutionsRaceNav=Race Committee App
|
||||
solutionsRaceHeadline=Race Committee App
|
||||
solutionsRaceText=The SAP Race Committee App delivers greater efficiency and control to race organizers by automating and simplifying their manual tasks and communication during running sailing regattas. The Race Committee App helps simplify the operation of running and managing race events to help race committees operate smarter.
|
||||
solutionsPostNav=Post-Race Analytics
|
||||
solutionsPostHeadline=Post-Race Analytics
|
||||
solutionsPostText=Access to data collected at sailing events gives sailors the opportunity to assess and analyse their performances to help develop strategies and sail better.<br> SAP Business Analytics solutions provide sailors, coaches, fans and media with tools to browse and analyse historical data across many regattas and races. SAP HANA allows them to learn about performance patterns, tendencies and sailor profiles in a simple, fast and efficient way in order to optimize their own performance and develop successful strategies for future regattas.
|
||||
solutionsTrainingNav=Training Diary
|
||||
solutionsTrainingHeadline=SAP Sail Better \u2013 STG Training Diary
|
||||
solutionsTrainingText=The STG Training Diary supports the daily documentation and analysis of an athlete\u2019s physical condition and training efforts in the areas of water training, physical training, boat work, mental, theory as well as other activities like education or travel.
|
||||
solutionsSimulatorNav=Strategy Simulator
|
||||
solutionsSimulatorHeadline=Strategy Simulator
|
||||
solutionsSimulatorText=Choosing the right strategy can provide great competitive advantage during a race. The Strategy Simulator simplifies determining the best sailing strategy for various wind conditions and water currents. Since wind and current can be changed in the simulation right away, the robustness of a strategy can be easily evaluated even for uncertain weather conditions.
|
||||
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"
|
||||
xmlns:g="urn:import:com.google.gwt.user.client.ui">
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<g:HTMLPanel>
|
||||
<s:error.ErrorMessage ui:field='errorMessage'/>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
|
||||
xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:c="urn:import:com.sap.sailing.gwt.common.client.controls.tabbar"
|
||||
xmlns:tabs="urn:import:com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs"
|
||||
xmlns:h="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.header">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:style>
|
||||
.header {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mainHeader {
|
||||
width: 66.6666666666667%;
|
||||
}
|
||||
|
||||
.sharingHeader {
|
||||
width: 33.3333333333333%;
|
||||
float: right;
|
||||
padding: 0 1rem;
|
||||
position:
|
||||
relative;
|
||||
padding: 1.333333333333333em 0;
|
||||
text-align: right;
|
||||
|
||||
background-color: maroon;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.breadcrumb, .intro {
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 0.866666666666667em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.intro {
|
||||
height: 5em;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<c:TabPanel ui:field="tabPanelUi">
|
||||
<c:header>
|
||||
<h:EventHeader ui:field="eventHeader" />
|
||||
</c:header>
|
||||
<c:tabcontent title="{i18n.overview}">
|
||||
<tabs:MultiregattaOverviewTabView />
|
||||
</c:tabcontent>
|
||||
<c:tabcontent title="{i18n.regattas}">
|
||||
<tabs:MultiregattaRegattasTabView />
|
||||
</c:tabcontent>
|
||||
<c:tabcontent title="{i18n.media}">
|
||||
<tabs:MultiregattaMediaTabView />
|
||||
</c:tabcontent>
|
||||
</c:TabPanel>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs;
|
||||
|
||||
import com.google.gwt.place.shared.Prefix;
|
||||
import com.sap.sailing.gwt.home.client.place.event.AbstractEventPlace;
|
||||
import com.sap.sailing.gwt.home.client.place.event.EventContext;
|
||||
import com.sap.sailing.gwt.home.client.place.event.EventPrefixes;
|
||||
import com.sap.sailing.gwt.home.client.place.event.multiregatta.AbstractMultiregattaEventPlace;
|
||||
|
||||
public class MultiregattaMediaPlace extends AbstractMultiregattaEventPlace {
|
||||
public MultiregattaMediaPlace(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public MultiregattaMediaPlace(EventContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Prefix(EventPrefixes.MultiregattaMedia)
|
||||
public static class Tokenizer extends AbstractEventPlace.Tokenizer<MultiregattaMediaPlace> {
|
||||
@Override
|
||||
protected MultiregattaMediaPlace getRealPlace(EventContext context) {
|
||||
return new MultiregattaMediaPlace(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
-181
@@ -1,181 +0,0 @@
|
||||
package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.AnchorElement;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
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.AcceptsOneWidget;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.sap.sailing.gwt.common.client.SharedResources;
|
||||
import com.sap.sailing.gwt.common.client.SharedResources.MainCss;
|
||||
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter;
|
||||
import com.sap.sailing.gwt.home.client.place.event.multiregatta.MultiregattaTabView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.overview.EventOverviewStage;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.eventregatta.EventRegattaList;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter.DropdownFilterList;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaList;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListStepsLegend;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLive;
|
||||
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshManager;
|
||||
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
|
||||
import com.sap.sailing.gwt.home.desktop.partials.statistics.StatisticsBox;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.SortedSetResult;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetEventStatisticsAction;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetLiveRacesForEventAction;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetRegattaListViewAction;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaWithProgressDTO;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
|
||||
/**
|
||||
* Created by pgtaboada on 25.11.14.
|
||||
*/
|
||||
public class MultiregattaOverviewTabView extends Composite implements MultiregattaTabView<MultiregattaOverviewPlace> {
|
||||
|
||||
private static final MainCss MAIN_CSS = SharedResources.INSTANCE.mainCss();
|
||||
|
||||
interface MyBinder extends UiBinder<HTMLPanel, MultiregattaOverviewTabView> {
|
||||
}
|
||||
|
||||
private static MyBinder ourUiBinder = GWT.create(MyBinder.class);
|
||||
|
||||
@UiField SimplePanel content;
|
||||
@UiField(provided = true) EventOverviewStage stage;
|
||||
@UiField(provided = true) RacesListLive racesListLive;
|
||||
@UiField DivElement newContentContainerUi;
|
||||
@UiField DivElement legendAndFilterUi;
|
||||
@UiField(provided = true) DropdownFilter<String> boatCategoryFilterUi;
|
||||
@UiField MultiRegattaListStepsLegend regattaProgressLegendUi;
|
||||
@UiField(provided = true) MultiRegattaList regattaListUi;
|
||||
@UiField AnchorElement regattaOverviewLinkUi;
|
||||
@UiField StatisticsBox statisticsBoxUi;
|
||||
private Presenter currentPresenter;
|
||||
|
||||
@Override
|
||||
public Class<MultiregattaOverviewPlace> getPlaceClassForActivation() {
|
||||
return MultiregattaOverviewPlace.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPresenter(EventMultiregattaView.Presenter currentPresenter) {
|
||||
this.currentPresenter = currentPresenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabView.State getState() {
|
||||
return TabView.State.VISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(MultiregattaOverviewPlace myPlace, AcceptsOneWidget contentArea) {
|
||||
stage = new EventOverviewStage(currentPresenter);
|
||||
racesListLive = new RacesListLive(currentPresenter, true);
|
||||
MultiregattaOverviewRegattasTabViewRegattaFilterList regattaFilterList = new MultiregattaOverviewRegattasTabViewRegattaFilterList();
|
||||
boatCategoryFilterUi = new DropdownFilter<String>(StringMessages.INSTANCE.allBoatClasses(), regattaFilterList);
|
||||
regattaListUi = new MultiRegattaList(currentPresenter, false);
|
||||
|
||||
initWidget(ourUiBinder.createAndBindUi(this));
|
||||
regattaOverviewLinkUi.setHref(currentPresenter.getRegattaOverviewLink());
|
||||
regattaOverviewLinkUi.addClassName(currentPresenter.isEventOrRegattaLive() ? MAIN_CSS.buttonred() : MAIN_CSS.buttonprimary());
|
||||
RefreshManager refreshManager = new RefreshManager(this, currentPresenter.getDispatch());
|
||||
stage.setupRefresh(refreshManager);
|
||||
refreshManager.add(racesListLive.getRefreshable(), new GetLiveRacesForEventAction(currentPresenter.getCtx().getEventDTO().getId()));
|
||||
|
||||
if (ExperimentalFeatures.SHOW_NEW_REGATTA_LIST) {
|
||||
refreshManager.add(regattaFilterList, new GetRegattaListViewAction(currentPresenter.getCtx().getEventDTO().getId()));
|
||||
refreshManager.add(statisticsBoxUi, new GetEventStatisticsAction(currentPresenter.getCtx().getEventDTO().getId(), true));
|
||||
content.removeFromParent();
|
||||
} else {
|
||||
boatCategoryFilterUi.removeFromParent();
|
||||
regattaProgressLegendUi.removeFromParent();
|
||||
regattaListUi.removeFromParent();
|
||||
newContentContainerUi.removeFromParent();
|
||||
// TODO: understand, and than move this into appropiate place (probably context)
|
||||
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
|
||||
@Override
|
||||
public void onSuccess(List<RaceGroupDTO> raceGroups) {
|
||||
if (raceGroups.size() > 0) {
|
||||
initView();
|
||||
} else {
|
||||
// createEventWithoutRegattasView(event, panel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
// createErrorView(
|
||||
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
|
||||
// caught, panel);
|
||||
}
|
||||
});
|
||||
}
|
||||
contentArea.setWidget(this);
|
||||
}
|
||||
|
||||
protected void initView() {
|
||||
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure = getRegattaStructure();
|
||||
EventRegattaList eventRegattaList = new EventRegattaList(regattaStructure, currentPresenter);
|
||||
content.setWidget(eventRegattaList);
|
||||
}
|
||||
|
||||
private Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> getRegattaStructure() {
|
||||
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> result = new HashMap<>();
|
||||
Map<String, RaceGroupDTO> raceGroupsMap = new HashMap<>();
|
||||
for (RaceGroupDTO raceGroup : currentPresenter.getCtx().getRaceGroups()) {
|
||||
raceGroupsMap.put(raceGroup.getName(), raceGroup);
|
||||
}
|
||||
for (LeaderboardGroupDTO leaderboardGroup : currentPresenter.getCtx().getLeaderboardGroups()) {
|
||||
for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) {
|
||||
String leaderboardName = leaderboard.name;
|
||||
result.put(leaderboardName, new Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>(
|
||||
raceGroupsMap.get(leaderboardName), leaderboard, leaderboardGroup));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
@Override
|
||||
public MultiregattaOverviewPlace placeToFire() {
|
||||
return new MultiregattaOverviewPlace(currentPresenter.getCtx());
|
||||
}
|
||||
|
||||
private class MultiregattaOverviewRegattasTabViewRegattaFilterList implements
|
||||
DropdownFilterList<String>, RefreshableWidget<SortedSetResult<RegattaWithProgressDTO>> {
|
||||
@Override
|
||||
public void setData(SortedSetResult<RegattaWithProgressDTO> data) {
|
||||
legendAndFilterUi.getStyle().setDisplay(data.isEmpty() ? Display.NONE : Display.BLOCK);
|
||||
regattaListUi.setData(data);
|
||||
boatCategoryFilterUi.updateFilterValues();
|
||||
}
|
||||
@Override
|
||||
public Collection<String> getSelectableValues() {
|
||||
return regattaListUi.getSelectableBoatCategories();
|
||||
}
|
||||
@Override
|
||||
public void onSelectFilter(String value) {
|
||||
regattaListUi.setVisibleBoatCategory(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
|
||||
xmlns:g='urn:import:com.google.gwt.user.client.ui'
|
||||
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.desktop.partials.statistics"
|
||||
xmlns:o="urn:import:com.sap.sailing.gwt.home.client.place.event.overview">
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:style>
|
||||
.legend_and_filter {
|
||||
text-align: right;
|
||||
}
|
||||
.legend_and_filter > div, .legend_and_filter > a {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<o:EventOverviewStage ui:field="stage" />
|
||||
<div class="{res.mediaCss.grid}" ui:field="newContentContainerUi">
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {res.mainCss.spacermarginbottommedium}">
|
||||
<p:raceListLive.RacesListLive ui:field="racesListLive" addStyleNames="{res.mainCss.spacermargin} {res.mainCss.spacermargintopmedium}" />
|
||||
<div class="{res.mainCss.spacermargintopmedium} {style.legend_and_filter}" ui:field="legendAndFilterUi" style="display:none;">
|
||||
<p:multiRegattaList.MultiRegattaListStepsLegend ui:field="regattaProgressLegendUi" />
|
||||
<p:listNavigation.DropdownFilter ui:field="boatCategoryFilterUi" />
|
||||
<a class="{res.mainCss.button} {res.mainCss.buttonstrong} {res.mainCss.buttonarrowrightwhite}"
|
||||
target="_blank" ui:field="regattaOverviewLinkUi">
|
||||
<ui:text from="{i18n.racesOverview}" />
|
||||
</a>
|
||||
</div>
|
||||
<p:multiRegattaList.MultiRegattaList ui:field="regattaListUi" />
|
||||
<s:StatisticsBox addStyleNames="{res.mainCss.spacermargin} {res.mainCss.spacermargintopmedium}" ui:field="statisticsBoxUi"/>
|
||||
</div>
|
||||
</div>
|
||||
<g:SimplePanel ui:field="content" />
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-178
@@ -1,178 +0,0 @@
|
||||
package com.sap.sailing.gwt.home.client.place.event.multiregatta.tabs;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.AnchorElement;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
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.AcceptsOneWidget;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.sap.sailing.gwt.common.client.SharedResources;
|
||||
import com.sap.sailing.gwt.common.client.SharedResources.MainCss;
|
||||
import com.sap.sailing.gwt.common.client.controls.tabbar.TabView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.multiregatta.EventMultiregattaView.Presenter;
|
||||
import com.sap.sailing.gwt.home.client.place.event.multiregatta.MultiregattaTabView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.eventregatta.EventRegattaList;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.listNavigation.DropdownFilter.DropdownFilterList;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaList;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.multiRegattaList.MultiRegattaListStepsLegend;
|
||||
import com.sap.sailing.gwt.home.client.place.event.partials.raceListLive.RacesListLive;
|
||||
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshManager;
|
||||
import com.sap.sailing.gwt.home.client.place.event.regatta.tabs.reload.RefreshableWidget;
|
||||
import com.sap.sailing.gwt.home.shared.ExperimentalFeatures;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.SortedSetResult;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetLiveRacesForEventAction;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.event.GetRegattaListViewAction;
|
||||
import com.sap.sailing.gwt.ui.shared.dispatch.regatta.RegattaWithProgressDTO;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
|
||||
/**
|
||||
* Created by pgtaboada on 25.11.14.
|
||||
*/
|
||||
public class MultiregattaRegattasTabView extends Composite implements MultiregattaTabView<MultiregattaRegattasPlace> {
|
||||
|
||||
private static final MainCss MAIN_CSS = SharedResources.INSTANCE.mainCss();
|
||||
|
||||
interface MyBinder extends UiBinder<HTMLPanel, MultiregattaRegattasTabView> {
|
||||
}
|
||||
|
||||
private static MyBinder ourUiBinder = GWT.create(MyBinder.class);
|
||||
|
||||
@UiField SimplePanel content;
|
||||
@UiField DivElement newContentContainerUi;
|
||||
@UiField(provided = true) RacesListLive racesListLiveUi;
|
||||
@UiField DivElement legendAndFilterUi;
|
||||
@UiField(provided = true) DropdownFilter<String> boatCategoryFilterUi;
|
||||
@UiField MultiRegattaListStepsLegend regattaProgressLegendUi;
|
||||
@UiField(provided = true) MultiRegattaList regattaListUi;
|
||||
@UiField AnchorElement regattaOverviewLinkUi;
|
||||
private Presenter currentPresenter;
|
||||
|
||||
@Override
|
||||
public Class<MultiregattaRegattasPlace> getPlaceClassForActivation() {
|
||||
return MultiregattaRegattasPlace.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPresenter(EventMultiregattaView.Presenter currentPresenter) {
|
||||
this.currentPresenter = currentPresenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabView.State getState() {
|
||||
return TabView.State.VISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(final MultiregattaRegattasPlace myPlace, final AcceptsOneWidget contentArea) {
|
||||
racesListLiveUi = new RacesListLive(currentPresenter, true);
|
||||
MultiregattaRegattasTabViewRegattaFilterList regattaFilterList = new MultiregattaRegattasTabViewRegattaFilterList();
|
||||
boatCategoryFilterUi = new DropdownFilter<String>(StringMessages.INSTANCE.allBoatClasses(), regattaFilterList);
|
||||
regattaListUi = new MultiRegattaList(currentPresenter, true);
|
||||
|
||||
initWidget(ourUiBinder.createAndBindUi(this));
|
||||
regattaOverviewLinkUi.setHref(currentPresenter.getRegattaOverviewLink());
|
||||
regattaOverviewLinkUi.addClassName(currentPresenter.isEventOrRegattaLive() ? MAIN_CSS.buttonred() : MAIN_CSS.buttonprimary());
|
||||
RefreshManager refreshManager = new RefreshManager(this, currentPresenter.getDispatch());
|
||||
refreshManager.add(racesListLiveUi.getRefreshable(), new GetLiveRacesForEventAction(currentPresenter.getCtx().getEventDTO().getId()));
|
||||
|
||||
if (ExperimentalFeatures.SHOW_NEW_REGATTA_LIST) {
|
||||
refreshManager.add(regattaFilterList, new GetRegattaListViewAction(currentPresenter.getCtx().getEventDTO().getId()));
|
||||
content.removeFromParent();
|
||||
} else {
|
||||
boatCategoryFilterUi.removeFromParent();
|
||||
regattaProgressLegendUi.removeFromParent();
|
||||
regattaListUi.removeFromParent();
|
||||
newContentContainerUi.removeFromParent();
|
||||
// TODO: understand, and than move this into appropiate place (probably context)
|
||||
currentPresenter.ensureRegattaStructure(new AsyncCallback<List<RaceGroupDTO>>() {
|
||||
@Override
|
||||
public void onSuccess(List<RaceGroupDTO> raceGroups) {
|
||||
if (raceGroups.size() > 0) {
|
||||
initView();
|
||||
} else {
|
||||
// createEventWithoutRegattasView(event, panel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
// createErrorView(
|
||||
// "Error while loading the regatta structure with service getRegattaStructureOfEvent()",
|
||||
// caught, panel);
|
||||
}
|
||||
});
|
||||
}
|
||||
contentArea.setWidget(this);
|
||||
}
|
||||
|
||||
protected void initView() {
|
||||
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> regattaStructure = getRegattaStructure();
|
||||
EventRegattaList eventRegattaList = new EventRegattaList(regattaStructure, currentPresenter);
|
||||
content.setWidget(eventRegattaList);
|
||||
}
|
||||
|
||||
private Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> getRegattaStructure() {
|
||||
Map<String, Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>> result = new HashMap<>();
|
||||
Map<String, RaceGroupDTO> raceGroupsMap = new HashMap<>();
|
||||
for (RaceGroupDTO raceGroup: currentPresenter.getCtx().getRaceGroups()) {
|
||||
raceGroupsMap.put(raceGroup.getName(), raceGroup);
|
||||
}
|
||||
|
||||
for (LeaderboardGroupDTO leaderboardGroup : currentPresenter.getCtx().getLeaderboardGroups()) {
|
||||
for(StrippedLeaderboardDTO leaderboard: leaderboardGroup.getLeaderboards()) {
|
||||
String leaderboardName = leaderboard.name;
|
||||
result.put(leaderboardName, new Triple<RaceGroupDTO, StrippedLeaderboardDTO, LeaderboardGroupDTO>(raceGroupsMap.get(leaderboardName),
|
||||
leaderboard, leaderboardGroup));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiregattaRegattasPlace placeToFire() {
|
||||
return new MultiregattaRegattasPlace(currentPresenter.getCtx());
|
||||
}
|
||||
|
||||
private class MultiregattaRegattasTabViewRegattaFilterList implements
|
||||
DropdownFilterList<String>, RefreshableWidget<SortedSetResult<RegattaWithProgressDTO>> {
|
||||
|
||||
@Override
|
||||
public void setData(SortedSetResult<RegattaWithProgressDTO> data) {
|
||||
legendAndFilterUi.getStyle().setDisplay(data.isEmpty() ? Display.NONE : Display.BLOCK);
|
||||
regattaListUi.setData(data);
|
||||
boatCategoryFilterUi.updateFilterValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getSelectableValues() {
|
||||
return regattaListUi.getSelectableBoatCategories();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelectFilter(String value) {
|
||||
regattaListUi.setVisibleBoatCategory(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'
|
||||
xmlns:p="urn:import:com.sap.sailing.gwt.home.client.place.event.partials">
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:style>
|
||||
.legend_and_filter {
|
||||
text-align: right;
|
||||
}
|
||||
.legend_and_filter > div, .legend_and_filter > a {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel>
|
||||
<div class="{res.mediaCss.grid}" ui:field="newContentContainerUi">
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {res.mainCss.spacermarginbottommedium}">
|
||||
<p:raceListLive.RacesListLive ui:field="racesListLiveUi" addStyleNames="{res.mainCss.spacermargintopmedium}" />
|
||||
<div class="{res.mainCss.spacermargintopmedium} {style.legend_and_filter}" ui:field="legendAndFilterUi" style="display:none;">
|
||||
<p:multiRegattaList.MultiRegattaListStepsLegend ui:field="regattaProgressLegendUi" />
|
||||
<p:listNavigation.DropdownFilter ui:field="boatCategoryFilterUi" />
|
||||
<a class="{res.mainCss.button} {res.mainCss.buttonstrong} {res.mainCss.buttonarrowrightwhite}"
|
||||
target="_blank" ui:field="regattaOverviewLinkUi">
|
||||
<ui:text from="{i18n.racesOverview}" />
|
||||
</a>
|
||||
</div>
|
||||
<p:multiRegattaList.MultiRegattaList ui:field="regattaListUi" />
|
||||
</div>
|
||||
</div>
|
||||
<g:SimplePanel ui:field="content" />
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
|
||||
xmlns:g="urn:import:com.google.gwt.user.client.ui">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
|
||||
<ui:style>
|
||||
.marginFix {
|
||||
margin-top: 2rem;
|
||||
|
||||
}
|
||||
</ui:style>
|
||||
|
||||
|
||||
<g:HTMLPanel>
|
||||
<div class="{res.mediaCss.grid} {style.marginFix}" >
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
|
||||
<h3><ui:text from="{i18n.competitorsAnalytics}" /></h3>
|
||||
</div>
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
|
||||
<ui:text from="{i18n.chooseChart}" />
|
||||
<g:ListBox ui:field="chartTypeSelectionListBox" />
|
||||
</div>
|
||||
<div class="{res.mediaCss.column}" style="margin-bottom: 1em;">
|
||||
<b><ui:text from="{i18n.chartSelectionHint}" /></b>
|
||||
</div>
|
||||
<div ui:field="competitorSelectionStateUi" class="{res.mediaCss.column}" style="margin-bottom: 1em;">
|
||||
</div>
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
||||
<g:HTMLPanel ui:field="oldCompetitorChartsPanel">
|
||||
</g:HTMLPanel>
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
|
||||
xmlns:g="urn:import:com.google.gwt.user.client.ui">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
|
||||
<g:HTMLPanel styleName=" {local_res.css.marginFix}">
|
||||
<div class="{res.mediaCss.grid}" >
|
||||
<div class="{res.mediaCss.small7} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
|
||||
<div ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></div>
|
||||
<div ui:field="hasLiveRaceDiv" class="{local_res.css.regattaleaderboard_meta_liverace}"></div>
|
||||
<div ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></div>
|
||||
</div>
|
||||
<div class="{res.mediaCss.small5} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
|
||||
<div class="{local_res.css.regattaleaderboard_meta_update}">
|
||||
<div ui:field="lastScoringUpdateTextDiv" class="{local_res.css.regattaleaderboard_meta_update_text}"></div>
|
||||
<div ui:field="lastScoringUpdateTimeDiv" class="{local_res.css.regattaleaderboard_meta_update_timestamp}"></div>
|
||||
</div>
|
||||
<g:Anchor ui:field="autoRefreshAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_reload}"></g:Anchor>
|
||||
<g:Anchor ui:field="settingsAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_settings_button}"></g:Anchor>
|
||||
<g:Anchor ui:field="fullscreenAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_fullscreen_button}"></g:Anchor>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="{res.mediaCss.grid}" >
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.letItScroll}">
|
||||
<table class="{local_res.css.regattaleaderboard_table}">
|
||||
<tr>
|
||||
<td>
|
||||
<g:HTMLPanel ui:field="oldLeaderboardPanel">
|
||||
</g:HTMLPanel>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
.oldMultiLeaderboardPanel {
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.place.event"
|
||||
xmlns:g="urn:import:com.google.gwt.user.client.ui">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
|
||||
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard.OldMultiLeaderboardResources" />
|
||||
<g:HTMLPanel styleName=" {local_res.css.marginFix}">
|
||||
<div class="{res.mediaCss.grid}" >
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
|
||||
<p ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></p>
|
||||
<p ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></p>
|
||||
</div>
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
|
||||
<div class="{local_res.css.regattaleaderboard_meta_update}">
|
||||
<p ui:field="lastScoringUpdateTextDiv" class="{local_res.css.regattaleaderboard_meta_update_text}"></p>
|
||||
<p ui:field="lastScoringUpdateTimeDiv" class="{local_res.css.regattaleaderboard_meta_update_timestamp}"></p>
|
||||
</div>
|
||||
<g:Anchor ui:field="autoRefreshAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_reload}"></g:Anchor>
|
||||
<g:Anchor ui:field="settingsAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_settings_button}"></g:Anchor>
|
||||
<g:Anchor ui:field="fullscreenAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_fullscreen_button}"></g:Anchor>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="{res.mediaCss.grid}" >
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns} {local_res.css.letItScroll}">
|
||||
<table class="{local_res.css.regattaleaderboard_table}">
|
||||
<tr>
|
||||
<td>
|
||||
<g:HTMLPanel ui:field="oldMultiLeaderboardPanel" styleName="{local_res2.css.oldMultiLeaderboardPanel}">
|
||||
</g:HTMLPanel>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.resources.client.ClientBundle;
|
||||
import com.google.gwt.resources.client.CssResource;
|
||||
|
||||
public interface OldMultiLeaderboardResources extends ClientBundle {
|
||||
public static final OldMultiLeaderboardResources INSTANCE = GWT.create(OldMultiLeaderboardResources.class);
|
||||
|
||||
@Source("com/sap/sailing/gwt/home/client/place/event/oldmultileaderboard/OldMultiLeaderboard.css")
|
||||
LocalCss css();
|
||||
|
||||
public interface LocalCss extends CssResource {
|
||||
String oldMultiLeaderboardPanel();
|
||||
}
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared" xmlns:m="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.message" xmlns:u="urn:import:com.sap.sailing.gwt.home.client.place.event.partials.updatesBox">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="i18n_ubi" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<g:HTMLPanel>
|
||||
<div class="{res.mainCss.spacer} {res.mainCss.spacersmall}"></div>
|
||||
<m:Message ui:field="message" />
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<g:SimplePanel ui:field="stage" addStyleNames="{res.mediaCss.small12} {res.mediaCss.columns}" />
|
||||
<div ui:field="updatesWrapperUi" class="{res.mediaCss.small12} {res.mediaCss.medium5} {res.mediaCss.large4} {res.mediaCss.columns}" style="display: none;">
|
||||
<u:UpdatesBox ui:field="updatesUi" addStyleNames="{res.mainCss.spacermargin} {res.mainCss.spacermargintopsmall} {res.mainCss.spacermarginonlyonsmall}" />
|
||||
</div>
|
||||
</div>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
.regatta {
|
||||
font-size: 15px;
|
||||
/* @alternate */ font-size: 1rem;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
padding: 1.333333333333333em 0;
|
||||
}
|
||||
.regatta[data-rendermode='compact'] {
|
||||
border-top: 1px solid #ccc;
|
||||
padding-left: 4em;
|
||||
padding-right: 4em;
|
||||
}
|
||||
.regatta[data-rendermode='compact'] .regatta_intro_details_itemhideoncompact {
|
||||
display: none;
|
||||
}
|
||||
.regatta[data-rendermode='link']:hover,
|
||||
.regatta[data-rendermode='link']:focus {
|
||||
background-color: #fcfcfc;
|
||||
}
|
||||
.regatta[data-rendermode='link']:nth-child(odd) {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.regatta[data-rendermode='link']:nth-child(odd):hover,
|
||||
.regatta[data-rendermode='link']:nth-child(odd):focus {
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
.regatta_intro {
|
||||
display: block;
|
||||
padding-left: 10.333333333333334em;
|
||||
min-height: 9.333333333333334em;
|
||||
position: relative;
|
||||
}
|
||||
.regatta_intro:hover,
|
||||
.regatta_intro:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
.regatta_intro_image {
|
||||
border: 1px solid #ccc;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.regatta_intro_header {
|
||||
margin-bottom: 0.666666666666667em;
|
||||
padding-top: 0.333333333333333em;
|
||||
padding-bottom: 0.666666666666667em;
|
||||
border-bottom: 1px solid #ccc;
|
||||
position: relative;
|
||||
}
|
||||
.regatta_intro_header_name {
|
||||
display: inline-block;
|
||||
font-size: 1.333333333333333em;
|
||||
margin: 0;
|
||||
margin-right: 0.266666666666667em;
|
||||
}
|
||||
.regatta_intro_header_namelink:hover,
|
||||
.regatta_intro_header_namelink:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.regatta_intro_header_details {
|
||||
text-align: right;
|
||||
}
|
||||
.regatta_intro_header_details_item {
|
||||
display: inline-block;
|
||||
padding: 0.2em 1em 0.2em 0;
|
||||
margin-right: 1em;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
.regatta_intro_header_details_item:last-child {
|
||||
padding-right: 0;
|
||||
margin-right: 0;
|
||||
border-right-width: 0;
|
||||
}
|
||||
.regatta_intro_header_details_item_value {
|
||||
color: #008fcc;
|
||||
font-weight: 700;
|
||||
}
|
||||
.regatta_intro_header_details_label {
|
||||
vertical-align: middle;
|
||||
margin-top: -0.2em;
|
||||
}
|
||||
.regatta_intro_phases {
|
||||
position: relative;
|
||||
padding-right: 10em;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding-bottom: 0.666666666666667em;
|
||||
}
|
||||
.regatta_intro_phases_phase {
|
||||
display: block;
|
||||
margin-right: 1.333333333333333em;
|
||||
padding: 0.133333333333333em 1.333333333333333em 0.133333333333333em 0;
|
||||
min-height: 2.666666666666667em;
|
||||
|
||||
}
|
||||
@media (min-width: 50em) {
|
||||
.regatta_intro_phases_phase {
|
||||
display: inline-block;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
}
|
||||
.regatta_intro_phases_phase_name {
|
||||
font-size: 0.866666666666667em;
|
||||
}
|
||||
.regatta_intro_phases_phase_races {
|
||||
display: inline-block;
|
||||
}
|
||||
.regatta_intro_phases_phase_races_race {
|
||||
display: inline-block;
|
||||
background-color: #ccc;
|
||||
height: 0.666666666666667em;
|
||||
width: 1.333333333333333em;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.regatta_intro_phases_phase_races_race[data-status='live'] {
|
||||
background-color: #f00;
|
||||
}
|
||||
.regatta_intro_phases_phase_races_race[data-status='finished'] {
|
||||
background-color: #f0ab00;
|
||||
}
|
||||
.regatta_intro_phases_leaderboardlink {
|
||||
text-transform: uppercase;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: #008FCC;
|
||||
color: white;
|
||||
}
|
||||
.regatta_intro_phases_leaderboardlink:hover {
|
||||
background-color: #0177ab;
|
||||
}
|
||||
|
||||
.regatta_intro_scheduled {
|
||||
padding-top: 0.8em;
|
||||
}
|
||||
.regatta_intro_results {
|
||||
padding-top: 0.6em;
|
||||
}
|
||||
.regatta_intro_results_competitor {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
display: inline-block;
|
||||
max-width: 32%;
|
||||
padding: 0.2em 1.333333333333333em;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
.regatta_intro_results_competitor:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
.regatta_intro_results_competitor:last-child {
|
||||
padding-right: 0;
|
||||
border-right-width: 0;
|
||||
}
|
||||
.regatta_intro_results_competitor_name {
|
||||
font-weight: 700;
|
||||
color: #008fcc;
|
||||
}
|
||||
.regatta_intro_fleets {
|
||||
width: 100%;
|
||||
}
|
||||
.regatta_intro_fleets_fleet {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.regatta_intro_fleets_fleet:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.regatta_intro_fleets_fleet_item {
|
||||
margin: 0.4em 0;
|
||||
padding: 0.4em 1.333333333333333em;
|
||||
border-left: 1px solid #ccc;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.regatta_intro_fleets_fleet_itemfirst {
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
border-left-width: 0;
|
||||
}
|
||||
.regatta_intro_fleets_fleet_item_value {
|
||||
font-weight: 700;
|
||||
color: #008fcc;
|
||||
}
|
||||
.regatta_intro_fleets_fleet_item_flag {
|
||||
width: 2em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.regatta_intro_fleets_fleet_live {
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
}
|
||||
-169
@@ -1,169 +0,0 @@
|
||||
package com.sap.sailing.gwt.home.client.place.event.partials;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.AnchorElement;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.HeadingElement;
|
||||
import com.google.gwt.dom.client.SpanElement;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.uibinder.client.UiHandler;
|
||||
import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.EventListener;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.common.client.BoatClassImageResolver;
|
||||
import com.sap.sailing.gwt.common.client.BoatClassImageResources;
|
||||
import com.sap.sailing.gwt.common.client.LinkUtil;
|
||||
import com.sap.sailing.gwt.home.client.place.event.EventView;
|
||||
import com.sap.sailing.gwt.home.client.place.event.EventView.Presenter;
|
||||
import com.sap.sailing.gwt.home.client.shared.LongNamesUtil;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceGroupSeriesDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.eventview.EventViewDTO;
|
||||
|
||||
public class Regatta extends Composite {
|
||||
private static RegattaUiBinder uiBinder = GWT.create(RegattaUiBinder.class);
|
||||
|
||||
interface RegattaUiBinder extends UiBinder<Widget, Regatta> {
|
||||
}
|
||||
|
||||
private final EventViewDTO event;
|
||||
private RaceGroupDTO raceGroup;
|
||||
private final List<RegattaPhase> phasesElements;
|
||||
private LeaderboardGroupDTO leaderboardGroup;
|
||||
private final boolean isSingleView;
|
||||
|
||||
@UiField DivElement regattaDiv;
|
||||
@UiField HeadingElement regattaNameHeading;
|
||||
@UiField DivElement leaderboardGroupName;
|
||||
@UiField DivElement leaderboardGroupNameDiv;
|
||||
// @UiField SpanElement scheduledStart;
|
||||
@UiField DivElement regattaPhasesPanel;
|
||||
@UiField DivElement regattaPhasesInfoDiv;
|
||||
|
||||
@UiField SpanElement competitorsCount;
|
||||
@UiField DivElement competitorsCountDiv;
|
||||
@UiField SpanElement racesCount;
|
||||
@UiField SpanElement trackedRacesCount;
|
||||
@UiField DivElement isLiveDiv;
|
||||
|
||||
@UiField Anchor regattaDetailsLink;
|
||||
|
||||
@UiField Image boatClassImage;
|
||||
@UiField
|
||||
AnchorElement boatClassLinkUi;
|
||||
|
||||
private Presenter presenter;
|
||||
|
||||
private PlaceNavigation<?> regattaNavigation;
|
||||
|
||||
public Regatta(boolean isSingleView, EventView.Presenter presenter) {
|
||||
this.event = presenter.getCtx().getEventDTO();
|
||||
this.isSingleView = isSingleView;
|
||||
this.presenter = presenter;
|
||||
|
||||
phasesElements = new ArrayList<RegattaPhase>();
|
||||
|
||||
RegattaResources.INSTANCE.css().ensureInjected();
|
||||
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
}
|
||||
|
||||
public void setData(LeaderboardGroupDTO leaderboardGroup, boolean hasMultipleLeaderboardGroups, StrippedLeaderboardDTO leaderboard,
|
||||
RaceGroupDTO raceGroup) {
|
||||
this.raceGroup = raceGroup;
|
||||
this.leaderboardGroup = leaderboardGroup;
|
||||
|
||||
if(isSingleView) {
|
||||
regattaDetailsLink.setVisible(false);
|
||||
} else {
|
||||
regattaNavigation = presenter.getRegattaNavigation(leaderboard.regattaName != null ? leaderboard.regattaName : leaderboard.name);
|
||||
regattaDetailsLink.setHref(regattaNavigation.getTargetUrl());
|
||||
boatClassLinkUi.setHref(regattaNavigation.getTargetUrl());
|
||||
Event.sinkEvents(boatClassLinkUi, Event.ONCLICK);
|
||||
Event.setEventListener(boatClassLinkUi, new EventListener() {
|
||||
@Override
|
||||
public void onBrowserEvent(Event event) {
|
||||
if (LinkUtil.handleLinkClick(event)) {
|
||||
event.preventDefault();
|
||||
regattaNavigation.goToPlace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
boolean hasLiveRace = leaderboard.hasLiveRace(presenter.getTimerForClientServerOffset().getLiveTimePointInMillis());
|
||||
if(!hasLiveRace) {
|
||||
isLiveDiv.getStyle().setDisplay(Display.NONE);
|
||||
}
|
||||
|
||||
// boolean isFinished... TODO
|
||||
if(raceGroup.boatClass != null) {
|
||||
boatClassImage.setResource(BoatClassImageResolver.getBoatClassIconResource(raceGroup.boatClass));
|
||||
} else {
|
||||
boatClassImage.setResource(BoatClassImageResources.INSTANCE.genericBoatClass());
|
||||
}
|
||||
|
||||
String regattaDisplayName = leaderboard.displayName != null ? leaderboard.displayName : leaderboard.name;
|
||||
regattaNameHeading.setInnerText(regattaDisplayName);
|
||||
if(hasMultipleLeaderboardGroups && leaderboardGroup.getName() != null) {
|
||||
leaderboardGroupName.setInnerText(LongNamesUtil.shortenLeaderboardGroupName(event.getDisplayName(), leaderboardGroup.getName()));
|
||||
leaderboardGroupName.setAttribute("data-labeltype", "group1");
|
||||
} else {
|
||||
leaderboardGroupNameDiv.removeFromParent();
|
||||
}
|
||||
|
||||
if(leaderboard.competitorsCount > 0) {
|
||||
competitorsCount.setInnerText(String.valueOf(leaderboard.competitorsCount));
|
||||
} else {
|
||||
competitorsCountDiv.getStyle().setDisplay(Display.NONE);
|
||||
}
|
||||
setRegattaProgress(leaderboard);
|
||||
}
|
||||
|
||||
private void setRegattaProgress(StrippedLeaderboardDTO leaderboard) {
|
||||
// clear first
|
||||
regattaPhasesPanel.removeAllChildren();
|
||||
phasesElements.clear();
|
||||
|
||||
if(raceGroup != null) {
|
||||
if(raceGroup.getSeries().size() == 0) {
|
||||
regattaPhasesInfoDiv.getStyle().setDisplay(Display.NONE);
|
||||
} else {
|
||||
for(RaceGroupSeriesDTO series: raceGroup.getSeries()) {
|
||||
RegattaPhase regattaPhase = new RegattaPhase(series, leaderboardGroup,
|
||||
leaderboard, raceGroup, presenter);
|
||||
regattaPhasesPanel.appendChild(regattaPhase.getElement());
|
||||
phasesElements.add(regattaPhase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
racesCount.setInnerText(String.valueOf(leaderboard.getRacesCount()));
|
||||
trackedRacesCount.setInnerText(String.valueOf(leaderboard.getTrackedRacesCount()));
|
||||
}
|
||||
|
||||
@UiHandler("regattaDetailsLink")
|
||||
void regattaDetailsLinkClicked(ClickEvent e) {
|
||||
handleClickEvent(e, regattaNavigation);
|
||||
}
|
||||
|
||||
private void handleClickEvent(ClickEvent e, PlaceNavigation<?> place) {
|
||||
if (LinkUtil.handleLinkClick((Event) e.getNativeEvent())) {
|
||||
place.goToPlace();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 826 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user