mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 22:15:26 +00:00
Merge branch 'master' into bug4339
This commit is contained in:
commit
39866326fe
123 files changed
+1927
-1326
No files matched your search
Binary file not shown.
+2
-6
@@ -1,12 +1,9 @@
|
||||
package com.sap.sailing.dashboards.gwt.client;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchSystem;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dispatch.impl.DashboardDispatchSystemImpl;
|
||||
import com.sap.sailing.gwt.ui.client.SailingService;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sse.gwt.client.EntryPointHelper;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceHelper;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
|
||||
@@ -24,8 +21,7 @@ public class DashboardClientFactoryImpl implements DashboardClientFactory{
|
||||
|
||||
public DashboardClientFactoryImpl() {
|
||||
dispatch = new DashboardDispatchSystemImpl();
|
||||
sailingService = GWT.create(SailingService.class);
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) sailingService, RemoteServiceMappingConstants.WEB_CONTEXT_PATH, RemoteServiceMappingConstants.sailingServiceRemotePath);
|
||||
sailingService = SailingServiceHelper.createSailingServiceInstance(false);
|
||||
dashboardFiveSecondsTimer = new Timer(PlayModes.Live);
|
||||
dashboardFiveSecondsTimer.setRefreshInterval(DASHBOARD_RERFRESH_INTERVAL);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ Export-Package: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.common.quadtree,
|
||||
com.sap.sailing.domain.common.quadtree.impl;x-friends:="com.sap.sailing.domain.test",
|
||||
com.sap.sailing.domain.common.racelog,
|
||||
com.sap.sailing.domain.common.sharding,
|
||||
com.sap.sailing.domain.common.racelog.tracking,
|
||||
com.sap.sailing.domain.common.racelog.utils,
|
||||
com.sap.sailing.domain.common.scalablevalue.impl,
|
||||
|
||||
+1
@@ -45,6 +45,7 @@ public enum BoatClassMasterdata {
|
||||
FARR_280 ("Farr 280", true, 8.72, 2.87, BoatHullType.MONOHULL, true, "F280", "F-280", "Farr-280"),
|
||||
FINN ("Finn", true, 4.50, 1.51, BoatHullType.MONOHULL, false),
|
||||
FLYING_DUTCHMAN ("Flying Dutchman", true, 6.10, 1.80, BoatHullType.MONOHULL, true, "FD"),
|
||||
FLYING_JUNIOR ("Flying Junior", true, 4.03, 1.50, BoatHullType.MONOHULL, true, "FJ"),
|
||||
FLYING_PHANTOM ("Flying Phantom", true, 5.52, 3.00, BoatHullType.CATAMARAN, true),
|
||||
FOLKBOAT ("Folkboat", true, 7.68, 2.20, BoatHullType.MONOHULL, false, "Folke", "Folkeboot"),
|
||||
FUN ("FUN", true, 7.20, 2.45, BoatHullType.MONOHULL, true, "FUN O.D.", "FUN OD", "Open FUN"),
|
||||
|
||||
+148
-87
@@ -5,10 +5,9 @@ import static com.sap.sailing.domain.common.SortingOrder.DESCENDING;
|
||||
import static com.sap.sailing.domain.common.SortingOrder.NONE;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
/**
|
||||
* Identifies details that can be requested from the racing service. Optionally, the details can specify a precision as
|
||||
@@ -244,11 +243,11 @@ public enum DetailType implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Special List of DetailTypes, that allows operators to select for example the RideHeight, that is usually only
|
||||
* selectable, if it already has data.
|
||||
* Special collection of {@link DetailType}s, that allows operators to select for example the RideHeight, that is
|
||||
* usually only selectable, if it already has data.
|
||||
*/
|
||||
public static List<DetailType> getAutoplayDetailTypesForChart() {
|
||||
List<DetailType> availableDetailsTypes = new ArrayList<>();
|
||||
public static Collection<DetailType> getAutoplayDetailTypesForChart() {
|
||||
final Collection<DetailType> availableDetailsTypes = new LinkedHashSet<>();
|
||||
availableDetailsTypes.add(DetailType.CHART_WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD);
|
||||
availableDetailsTypes.add(DetailType.LEG_CURRENT_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
availableDetailsTypes.add(DetailType.LEG_DISTANCE_TRAVELED);
|
||||
@@ -266,8 +265,8 @@ public enum DetailType implements Serializable {
|
||||
return availableDetailsTypes;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceExpeditionDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getRaceExpeditionDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(EXPEDITION_RACE_AWA);
|
||||
allowed.add(EXPEDITION_RACE_AWS);
|
||||
allowed.add(EXPEDITION_RACE_TWA);
|
||||
@@ -310,15 +309,8 @@ public enum DetailType implements Serializable {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegExtendedBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
allowed.add(DetailType.BRAVOEXTENDED_LEG_CURRENT_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_LEG_CURRENT_DURATION_FOILED_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceExtendedBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getRaceExtendedBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(DetailType.BRAVOEXTENDED_RACE_CURRENT_PORT_DAGGERBOARD_RAKE);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_RACE_CURRENT_STBD_DAGGERBOARD_RAKE);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_RACE_CURRENT_PORT_RUDDER_RAKE);
|
||||
@@ -340,24 +332,28 @@ public enum DetailType implements Serializable {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getRaceBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(DetailType.BRAVO_RACE_HEEL_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_RACE_PITCH_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_RACE_CURRENT_RIDE_HEIGHT_IN_METERS);
|
||||
allowed.add(DetailType.RACE_CURRENT_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(DetailType.RACE_CURRENT_DURATION_FOILED_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegBravoDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getLegBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(DetailType.BRAVO_LEG_CURRENT_HEEL_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_LEG_CURRENT_PITCH_IN_DEGREES);
|
||||
allowed.add(DetailType.BRAVO_LEG_CURRENT_RIDE_HEIGHT_IN_METERS);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_LEG_CURRENT_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(DetailType.BRAVOEXTENDED_LEG_CURRENT_DURATION_FOILED_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getAllRaceDetailTypes() {
|
||||
ArrayList<DetailType> allowed = new ArrayList<>();
|
||||
public static Collection<DetailType> getAllRaceDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(RACE_GAP_TO_LEADER_IN_SECONDS);
|
||||
allowed.add(RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(RACE_DISTANCE_TRAVELED);
|
||||
@@ -366,7 +362,6 @@ public enum DetailType implements Serializable {
|
||||
allowed.add(RACE_CALCULATED_TIME_TRAVELED);
|
||||
allowed.add(RACE_CALCULATED_TIME_AT_ESTIMATED_ARRIVAL_AT_COMPETITOR_FARTHEST_AHEAD);
|
||||
allowed.add(RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(BRAVO_RACE_CURRENT_RIDE_HEIGHT_IN_METERS);
|
||||
allowed.add(RACE_CURRENT_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(RACE_CURRENT_DURATION_FOILED_IN_SECONDS);
|
||||
allowed.add(RACE_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD_IN_METERS);
|
||||
@@ -388,7 +383,7 @@ public enum DetailType implements Serializable {
|
||||
* @return
|
||||
*/
|
||||
public static Collection<DetailType> getAllNonRestrictedDetailTypes() {
|
||||
List<DetailType> all = new ArrayList<>(Arrays.asList(values()));
|
||||
final Collection<DetailType> all = new LinkedHashSet<>(Arrays.asList(values()));
|
||||
all.removeAll(getRaceBravoDetailTypes());
|
||||
all.removeAll(getLegBravoDetailTypes());
|
||||
all.removeAll(getRaceExtendedBravoDetailTypes());
|
||||
@@ -398,83 +393,150 @@ public enum DetailType implements Serializable {
|
||||
return all;
|
||||
}
|
||||
|
||||
public static List<DetailType> getAvailableOverallDetailColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.REGATTA_RANK, DetailType.OVERALL_TOTAL_DISTANCE_TRAVELED,
|
||||
DetailType.OVERALL_TOTAL_AVERAGE_SPEED_OVER_GROUND, DetailType.OVERALL_TOTAL_TIME_SAILED_IN_SECONDS,
|
||||
DetailType.OVERALL_MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS, DetailType.OVERALL_TIME_ON_TIME_FACTOR,
|
||||
DetailType.OVERALL_TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE,
|
||||
DetailType.OVERALL_TOTAL_SCORED_RACE_COUNT, TOTAL_TIME_SAILED_UPWIND_IN_SECONDS,
|
||||
TOTAL_TIME_SAILED_REACHING_IN_SECONDS, TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS });
|
||||
public static Collection<DetailType> getAvailableOverallDetailColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(REGATTA_RANK);
|
||||
allowed.add(OVERALL_TOTAL_DISTANCE_TRAVELED);
|
||||
allowed.add(OVERALL_TOTAL_AVERAGE_SPEED_OVER_GROUND);
|
||||
allowed.add(OVERALL_TOTAL_TIME_SAILED_IN_SECONDS);
|
||||
allowed.add(OVERALL_MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(OVERALL_TIME_ON_TIME_FACTOR);
|
||||
allowed.add(OVERALL_TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE);
|
||||
allowed.add(OVERALL_TOTAL_SCORED_RACE_COUNT);
|
||||
allowed.add(TOTAL_TIME_SAILED_UPWIND_IN_SECONDS);
|
||||
allowed.add(TOTAL_TIME_SAILED_REACHING_IN_SECONDS);
|
||||
allowed.add(TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getOverallBravoDetailTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.OVERALL_TOTAL_DISTANCE_FOILED_IN_METERS,
|
||||
OVERALL_TOTAL_DURATION_FOILED_IN_SECONDS });
|
||||
public static Collection<DetailType> getOverallBravoDetailTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(OVERALL_TOTAL_DISTANCE_FOILED_IN_METERS);
|
||||
allowed.add(OVERALL_TOTAL_DURATION_FOILED_IN_SECONDS);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegDetailColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS,
|
||||
DetailType.LEG_DISTANCE_TRAVELED, DetailType.LEG_DISTANCE_TRAVELED_INCLUDING_GATE_START,
|
||||
DetailType.LEG_GAP_TO_LEADER_IN_SECONDS, DetailType.LEG_GAP_CHANGE_SINCE_LEG_START_IN_SECONDS,
|
||||
DetailType.LEG_SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED,
|
||||
DetailType.LEG_CURRENT_SPEED_OVER_GROUND_IN_KNOTS, DetailType.LEG_WINDWARD_DISTANCE_TO_GO_IN_METERS,
|
||||
DetailType.NUMBER_OF_MANEUVERS, DetailType.LEG_ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS,
|
||||
DetailType.LEG_VELOCITY_MADE_GOOD_IN_KNOTS, DetailType.LEG_TIME_TRAVELED,
|
||||
DetailType.LEG_CORRECTED_TIME_TRAVELED, DetailType.LEG_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS,
|
||||
DetailType.LEG_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS, DetailType.LEG_RANK_GAIN });
|
||||
public static Collection<DetailType> getLegDetailColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(LEG_DISTANCE_TRAVELED);
|
||||
allowed.add(LEG_DISTANCE_TRAVELED_INCLUDING_GATE_START);
|
||||
allowed.add(LEG_GAP_TO_LEADER_IN_SECONDS);
|
||||
allowed.add(LEG_GAP_CHANGE_SINCE_LEG_START_IN_SECONDS);
|
||||
allowed.add(LEG_SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED);
|
||||
allowed.add(LEG_CURRENT_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
allowed.add(LEG_WINDWARD_DISTANCE_TO_GO_IN_METERS);
|
||||
allowed.add(NUMBER_OF_MANEUVERS);
|
||||
allowed.add(LEG_ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS);
|
||||
allowed.add(LEG_VELOCITY_MADE_GOOD_IN_KNOTS);
|
||||
allowed.add(LEG_TIME_TRAVELED);
|
||||
allowed.add(LEG_CORRECTED_TIME_TRAVELED);
|
||||
allowed.add(LEG_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS);
|
||||
allowed.add(LEG_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS);
|
||||
allowed.add(LEG_RANK_GAIN);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getRaceStartAnalysisColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { DetailType.RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START,
|
||||
DetailType.RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START, DetailType.DISTANCE_TO_START_AT_RACE_START,
|
||||
DetailType.TIME_BETWEEN_RACE_START_AND_COMPETITOR_START, DetailType.SPEED_OVER_GROUND_AT_RACE_START,
|
||||
DetailType.SPEED_OVER_GROUND_WHEN_PASSING_START,
|
||||
DetailType.DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS,
|
||||
DetailType.START_TACK });
|
||||
public static Collection<DetailType> getRaceStartAnalysisColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START);
|
||||
allowed.add(RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START);
|
||||
allowed.add(DISTANCE_TO_START_AT_RACE_START);
|
||||
allowed.add(TIME_BETWEEN_RACE_START_AND_COMPETITOR_START);
|
||||
allowed.add(SPEED_OVER_GROUND_AT_RACE_START);
|
||||
allowed.add(SPEED_OVER_GROUND_WHEN_PASSING_START);
|
||||
allowed.add(DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS);
|
||||
allowed.add(START_TACK);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<DetailType> getLegExpeditionDetailColumnTypes() {
|
||||
return Arrays.asList(new DetailType[] { EXPEDITION_LEG_AWA, EXPEDITION_LEG_AWS, EXPEDITION_LEG_TWA,
|
||||
EXPEDITION_LEG_TWS, EXPEDITION_LEG_TWD, EXPEDITION_LEG_TARG_TWA, EXPEDITION_LEG_BOAT_SPEED,
|
||||
EXPEDITION_LEG_TARG_BOAT_SPEED, EXPEDITION_LEG_SOG, EXPEDITION_LEG_COG, EXPEDITION_LEG_FORESTAY_LOAD,
|
||||
EXPEDITION_LEG_RAKE, EXPEDITION_LEG_COURSE, EXPEDITION_LEG_HEADING, EXPEDITION_LEG_VMG,
|
||||
EXPEDITION_LEG_VMG_TARG_VMG_DELTA, EXPEDITION_LEG_RATE_OF_TURN, EXPEDITION_LEG_RUDDER_ANGLE,
|
||||
EXPEDITION_LEG_TARGET_HEEL, EXPEDITION_LEG_TIME_TO_PORT_LAYLINE,
|
||||
EXPEDITION_LEG_TIME_TO_STB_LAYLINE, EXPEDITION_LEG_DIST_TO_PORT_LAYLINE,
|
||||
EXPEDITION_LEG_DIST_TO_STB_LAYLINE, EXPEDITION_LEG_TIME_TO_GUN, EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_LEG_TIME_TO_PIN, EXPEDITION_LEG_TIME_TO_BURN_TO_LINE,
|
||||
EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT, EXPEDITION_LEG_TIME_TO_BURN_TO_PIN,
|
||||
EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT, EXPEDITION_LEG_DISTANCE_TO_PIN,
|
||||
EXPEDITION_LEG_DISTANCE_BELOW_LINE, EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION, EXPEDITION_LEG_BARO,
|
||||
EXPEDITION_LEG_LOAD_S, EXPEDITION_LEG_LOAD_P, EXPEDITION_LEG_JIB_CAR_PORT, EXPEDITION_LEG_JIB_CAR_STBD,
|
||||
EXPEDITION_LEG_MAST_BUTT });
|
||||
public static Collection<DetailType> getLegExpeditionDetailColumnTypes() {
|
||||
final Collection<DetailType> allowed = new LinkedHashSet<>();
|
||||
allowed.add(EXPEDITION_LEG_AWA);
|
||||
allowed.add(EXPEDITION_LEG_AWS);
|
||||
allowed.add(EXPEDITION_LEG_TWA);
|
||||
allowed.add(EXPEDITION_LEG_TWS);
|
||||
allowed.add(EXPEDITION_LEG_TWD);
|
||||
allowed.add(EXPEDITION_LEG_TARG_TWA);
|
||||
allowed.add(EXPEDITION_LEG_BOAT_SPEED);
|
||||
allowed.add(EXPEDITION_LEG_TARG_BOAT_SPEED);
|
||||
allowed.add(EXPEDITION_LEG_SOG);
|
||||
allowed.add(EXPEDITION_LEG_COG);
|
||||
allowed.add(EXPEDITION_LEG_FORESTAY_LOAD);
|
||||
allowed.add(EXPEDITION_LEG_RAKE);
|
||||
allowed.add(EXPEDITION_LEG_COURSE);
|
||||
allowed.add(EXPEDITION_LEG_HEADING);
|
||||
allowed.add(EXPEDITION_LEG_VMG);
|
||||
allowed.add(EXPEDITION_LEG_VMG_TARG_VMG_DELTA);
|
||||
allowed.add(EXPEDITION_LEG_RATE_OF_TURN);
|
||||
allowed.add(EXPEDITION_LEG_RUDDER_ANGLE);
|
||||
allowed.add(EXPEDITION_LEG_TARGET_HEEL);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_PORT_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_STB_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_DIST_TO_PORT_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_DIST_TO_STB_LAYLINE);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_GUN);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_PIN);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_BURN_TO_LINE);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT);
|
||||
allowed.add(EXPEDITION_LEG_TIME_TO_BURN_TO_PIN);
|
||||
allowed.add(EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT);
|
||||
allowed.add(EXPEDITION_LEG_DISTANCE_TO_PIN);
|
||||
allowed.add(EXPEDITION_LEG_DISTANCE_BELOW_LINE);
|
||||
allowed.add(EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION);
|
||||
allowed.add(EXPEDITION_LEG_BARO);
|
||||
allowed.add(EXPEDITION_LEG_LOAD_S);
|
||||
allowed.add(EXPEDITION_LEG_LOAD_P);
|
||||
allowed.add(EXPEDITION_LEG_JIB_CAR_PORT);
|
||||
allowed.add(EXPEDITION_LEG_JIB_CAR_STBD);
|
||||
allowed.add(EXPEDITION_LEG_MAST_BUTT);
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not yet implemented types can be added here, they will be hidden from any user under all circumstances
|
||||
*/
|
||||
public static List<DetailType> getDisabledDetailColumTypes() {
|
||||
return Arrays.asList(new DetailType[] { EXPEDITION_LEG_TARG_TWA, EXPEDITION_LEG_VMG,
|
||||
EXPEDITION_LEG_VMG_TARG_VMG_DELTA, EXPEDITION_LEG_RATE_OF_TURN, EXPEDITION_LEG_RUDDER_ANGLE,
|
||||
EXPEDITION_LEG_TIME_TO_PORT_LAYLINE, EXPEDITION_LEG_TIME_TO_STB_LAYLINE,
|
||||
EXPEDITION_LEG_DIST_TO_PORT_LAYLINE, EXPEDITION_LEG_DIST_TO_STB_LAYLINE,
|
||||
EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT, EXPEDITION_LEG_TIME_TO_PIN, EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_LEG_TIME_TO_BURN_TO_PIN, EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_LEG_DISTANCE_TO_PIN, EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION, EXPEDITION_RACE_TARG_TWA,
|
||||
EXPEDITION_RACE_VMG, EXPEDITION_RACE_VMG_TARG_VMG_DELTA,
|
||||
EXPEDITION_RACE_RUDDER_ANGLE, EXPEDITION_RACE_TIME_TO_PORT_LAYLINE, EXPEDITION_RACE_TIME_TO_STB_LAYLINE,
|
||||
EXPEDITION_RACE_DIST_TO_PORT_LAYLINE, EXPEDITION_RACE_DIST_TO_STB_LAYLINE,
|
||||
EXPEDITION_RACE_TIME_TO_COMMITTEE_BOAT, EXPEDITION_RACE_TIME_TO_PIN,
|
||||
EXPEDITION_RACE_TIME_TO_BURN_TO_PIN, EXPEDITION_RACE_TIME_TO_BURN_TO_COMMITTEE_BOAT,
|
||||
EXPEDITION_RACE_DISTANCE_TO_COMMITTEE_BOAT, EXPEDITION_RACE_DISTANCE_TO_PIN,
|
||||
EXPEDITION_RACE_LINE_SQUARE_FOR_WIND_DIRECTION });
|
||||
public static Collection<DetailType> getDisabledDetailColumTypes() {
|
||||
final Collection<DetailType> disabled = new LinkedHashSet<>();
|
||||
disabled.add(EXPEDITION_LEG_TARG_TWA);
|
||||
disabled.add(EXPEDITION_LEG_VMG);
|
||||
disabled.add(EXPEDITION_LEG_VMG_TARG_VMG_DELTA);
|
||||
disabled.add(EXPEDITION_LEG_RATE_OF_TURN);
|
||||
disabled.add(EXPEDITION_LEG_RUDDER_ANGLE);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_DIST_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_DIST_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_PIN);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_BURN_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_LEG_TIME_TO_BURN_TO_PIN);
|
||||
disabled.add(EXPEDITION_LEG_DISTANCE_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_LEG_DISTANCE_TO_PIN);
|
||||
disabled.add(EXPEDITION_LEG_LINE_SQUARE_FOR_WIND_DIRECTION);
|
||||
disabled.add(EXPEDITION_RACE_TARG_TWA);
|
||||
disabled.add(EXPEDITION_RACE_VMG);
|
||||
disabled.add(EXPEDITION_RACE_VMG_TARG_VMG_DELTA);
|
||||
disabled.add(EXPEDITION_RACE_RUDDER_ANGLE);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_DIST_TO_PORT_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_DIST_TO_STB_LAYLINE);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_PIN);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_BURN_TO_PIN);
|
||||
disabled.add(EXPEDITION_RACE_TIME_TO_BURN_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_RACE_DISTANCE_TO_COMMITTEE_BOAT);
|
||||
disabled.add(EXPEDITION_RACE_DISTANCE_TO_PIN);
|
||||
disabled.add(EXPEDITION_RACE_LINE_SQUARE_FOR_WIND_DIRECTION);
|
||||
return disabled;
|
||||
}
|
||||
|
||||
public static List<DetailType> getAllLegDetailColumnTypes() {
|
||||
ArrayList<DetailType> all = new ArrayList<>();
|
||||
public static Collection<DetailType> getAllLegDetailColumnTypes() {
|
||||
final Collection<DetailType> all = new LinkedHashSet<>();
|
||||
all.addAll(getLegDetailColumnTypes());
|
||||
all.addAll(getLegBravoDetailTypes());
|
||||
all.addAll(getLegExtendedBravoDetailTypes());
|
||||
all.addAll(getLegExpeditionDetailColumnTypes());
|
||||
return all;
|
||||
}
|
||||
@@ -498,11 +560,10 @@ public enum DetailType implements Serializable {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not restore " + value + " to an DetailType enum");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.sap.sailing.domain.common.sharding;
|
||||
|
||||
/**
|
||||
* Enum that defines all sharding types known by the system.
|
||||
*
|
||||
* For a sharding to work, we need both client and backend properly identifying a shard.
|
||||
*
|
||||
* While the client has to properly deliver sharding information on each request, the server side
|
||||
* infrastructure must be able to identify the information and properly route the requests.
|
||||
*
|
||||
* The current implementation uses a SUFFIX appended the GWT RPC URLs (allowing path based routing), so that each call to the server
|
||||
* propagates the sharding information through the url.
|
||||
*
|
||||
* A load balancer can be used to properly route each request to the corresponding server node. The first
|
||||
* sharding implemented is the sharding by leaderboard name.
|
||||
*
|
||||
* The suffix appended to the request URL consists of two parts: a prefix that is used to identify the type of shard
|
||||
* and a payload that will be used to identify the shard.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public enum ShardingType {
|
||||
LEADERBOARDNAME("/leaderboard/");
|
||||
|
||||
private String prefix;
|
||||
|
||||
private ShardingType(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public String encodeIfNeeded(String shardingInfo) {
|
||||
if (shardingInfo.startsWith(prefix)) {
|
||||
return shardingInfo;
|
||||
}
|
||||
return new StringBuilder().append(prefix)
|
||||
.append(normalize(shardingInfo))
|
||||
.toString();
|
||||
}
|
||||
|
||||
private String normalize(String replace) {
|
||||
char[] chars = replace.toCharArray();
|
||||
StringBuilder answer = new StringBuilder();
|
||||
for(int i = 0;i<chars.length;i++) {
|
||||
char c = chars[i];
|
||||
if (c > 47 && c < 58) { // digits
|
||||
answer.append(c);
|
||||
} else if (c > 64 && c < 91) { // uppercase letters
|
||||
answer.append(c);
|
||||
} else if (c > 69 && c < 123) { // lowercase letters
|
||||
answer.append(c);
|
||||
} else {
|
||||
answer.append("_");
|
||||
}
|
||||
}
|
||||
return answer.toString();
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
+7
@@ -10,6 +10,7 @@ import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
|
||||
import com.sap.sailing.domain.base.configuration.procedures.SWCStartConfiguration;
|
||||
import com.sap.sailing.domain.common.CourseDesignerMode;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
* Interface holding configuration options for a Regatta, including configurations for
|
||||
@@ -26,6 +27,12 @@ public interface RegattaConfiguration extends Serializable, Cloneable {
|
||||
* Gets the default {@link RacingProcedureType} for races configured.
|
||||
*/
|
||||
RacingProcedureType getDefaultRacingProcedureType();
|
||||
|
||||
/**
|
||||
* Gets the default protest time duration. May be {@code null} in case no default is set for the
|
||||
* regatta.
|
||||
*/
|
||||
Duration getDefaultProtestTimeDuration();
|
||||
|
||||
/**
|
||||
* Gets the configuration for RRS26 races.
|
||||
|
||||
+2
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
|
||||
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
||||
import com.sap.sailing.domain.common.CourseDesignerMode;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
* Is empty, does nothing on store and load.
|
||||
@@ -17,6 +18,7 @@ public class EmptyRegattaConfiguration extends RegattaConfigurationImpl implemen
|
||||
public RegattaConfiguration load() {
|
||||
setDefaultRacingProcedureType(RacingProcedureType.UNKNOWN);
|
||||
setDefaultCourseDesignerMode(CourseDesignerMode.UNKNOWN);
|
||||
setDefaultProtestTimeDuration(Duration.ONE_MINUTE.times(90));
|
||||
setRRS26Configuration(new RRS26ConfigurationImpl());
|
||||
setSWCStartConfiguration(new SWCStartConfigurationImpl());
|
||||
setGateStartConfiguration(new GateStartConfigurationImpl());
|
||||
|
||||
+15
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
|
||||
import com.sap.sailing.domain.base.configuration.procedures.SWCStartConfiguration;
|
||||
import com.sap.sailing.domain.common.CourseDesignerMode;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
public class RegattaConfigurationImpl implements RegattaConfiguration {
|
||||
|
||||
@@ -16,6 +17,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
||||
|
||||
private RacingProcedureType defaultRacingProcedureType;
|
||||
private CourseDesignerMode defaultCourseDesignerMode;
|
||||
private Duration defaultProtestTimeDuration;
|
||||
|
||||
private RRS26Configuration rrs26Configuration;
|
||||
private SWCStartConfiguration swcStartConfiguration;
|
||||
@@ -42,6 +44,15 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
||||
defaultCourseDesignerMode = mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getDefaultProtestTimeDuration() {
|
||||
return defaultProtestTimeDuration;
|
||||
}
|
||||
|
||||
public void setDefaultProtestTimeDuration(Duration defaultProtestTimeDuration) {
|
||||
this.defaultProtestTimeDuration = defaultProtestTimeDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RRS26Configuration getRRS26Configuration() {
|
||||
return rrs26Configuration;
|
||||
@@ -101,6 +112,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
||||
RegattaConfigurationImpl copy = new RegattaConfigurationImpl();
|
||||
copy.setDefaultRacingProcedureType(defaultRacingProcedureType);
|
||||
copy.setDefaultCourseDesignerMode(defaultCourseDesignerMode);
|
||||
copy.setDefaultProtestTimeDuration(defaultProtestTimeDuration);
|
||||
copy.setRRS26Configuration(rrs26Configuration);
|
||||
copy.setSWCStartConfiguration(swcStartConfiguration);
|
||||
copy.setGateStartConfiguration(gateStartConfiguration);
|
||||
@@ -120,6 +132,9 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
||||
if (update.getDefaultRacingProcedureType() != null) {
|
||||
target.setDefaultRacingProcedureType(update.getDefaultRacingProcedureType());
|
||||
}
|
||||
if (update.getDefaultProtestTimeDuration() != null) {
|
||||
target.setDefaultProtestTimeDuration(update.getDefaultProtestTimeDuration());
|
||||
}
|
||||
if (update.getRRS26Configuration() != null) {
|
||||
target.setRRS26Configuration(
|
||||
(RRS26Configuration) target.getRRS26Configuration().merge(update.getRRS26Configuration()));
|
||||
|
||||
@@ -31,6 +31,7 @@ Export-Package: com.sap.sailing.domain.base,
|
||||
com.sap.sailing.domain.trackimport,
|
||||
com.sap.sailing.domain.tracking,
|
||||
com.sap.sailing.domain.tracking.impl,
|
||||
com.sap.sailing.domain.sharding,
|
||||
com.sap.sailing.domain.windfinder,
|
||||
com.sap.sailing.util,
|
||||
com.sap.sailing.util.impl;x-friends:="com.sap.sailing.server.replication,com.sap.sailing.domain.test"
|
||||
|
||||
+5
@@ -12,7 +12,9 @@ import java.util.logging.Logger;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.sharding.ShardingContext;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
@@ -274,6 +276,7 @@ public class LiveLeaderboardUpdater implements Runnable {
|
||||
public void run() {
|
||||
assert running;
|
||||
try {
|
||||
ShardingContext.setShardingConstraint(ShardingType.LEADERBOARDNAME, leaderboard.getName());
|
||||
logger.info("Starting " + LiveLeaderboardUpdater.class.getSimpleName() + " thread for leaderboard "
|
||||
+ leaderboard.getName());
|
||||
// interrupt the current thread if not producing a single result within the overall timeout
|
||||
@@ -326,6 +329,8 @@ public class LiveLeaderboardUpdater implements Runnable {
|
||||
notifyAll();
|
||||
}
|
||||
logger.log(Level.SEVERE, "exception updating live leaderboard "+leaderboard.getName(), e);
|
||||
} finally {
|
||||
ShardingContext.clearShardingConstraint(ShardingType.LEADERBOARDNAME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -55,6 +55,7 @@ import com.sap.sailing.domain.common.dto.LegEntryDTO;
|
||||
import com.sap.sailing.domain.common.dto.MetaLeaderboardRaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceDTO;
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.common.tracking.BravoExtendedFix;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
@@ -68,6 +69,7 @@ import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.CompetitorRankingInfo;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||
import com.sap.sailing.domain.sharding.ShardingContext;
|
||||
import com.sap.sailing.domain.tracking.BravoFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
@@ -355,6 +357,7 @@ public abstract class AbstractLeaderboardWithCache implements Leaderboard {
|
||||
final boolean waitForLatestAnalyses, TrackedRegattaRegistry trackedRegattaRegistry, final DomainFactory baseDomainFactory,
|
||||
final boolean fillTotalPointsUncorrected)
|
||||
throws NoWindException {
|
||||
ShardingContext.checkConstraint(ShardingType.LEADERBOARDNAME, getName());
|
||||
long startOfRequestHandling = System.currentTimeMillis();
|
||||
final LeaderboardDTOCalculationReuseCache cache = new LeaderboardDTOCalculationReuseCache(timePoint);
|
||||
final BoatClass boatClass = getBoatClass();
|
||||
|
||||
+166
-124
@@ -52,16 +52,17 @@ import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* Base implementation for various types of leaderboards. The {@link RaceColumnListener} implementation forwards events
|
||||
* received to all {@link RaceColumnListener} subscribed with this leaderboard. To which objects this leaderboard subscribes
|
||||
* as {@link RaceColumnListener} is left to the concrete subclasses to implement, but the race columns seem like useful
|
||||
* candidates.
|
||||
* received to all {@link RaceColumnListener} subscribed with this leaderboard. To which objects this leaderboard
|
||||
* subscribes as {@link RaceColumnListener} is left to the concrete subclasses to implement, but the race columns seem
|
||||
* like useful candidates.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardWithCache implements Leaderboard, RaceColumnListener {
|
||||
public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardWithCache
|
||||
implements Leaderboard, RaceColumnListener {
|
||||
private static final long serialVersionUID = 330156778603279333L;
|
||||
|
||||
|
||||
static final Double DOUBLE_0 = new Double(0);
|
||||
|
||||
private final SettableScoreCorrection scoreCorrection;
|
||||
@@ -75,15 +76,15 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
private final Map<Competitor, String> displayNames;
|
||||
|
||||
/**
|
||||
* Backs the {@link #getCarriedPoints(Competitor)} API with data. Can be used to prime this leaderboard
|
||||
* with aggregated results of races not tracked / displayed by this leaderboard in detail. The points
|
||||
* provided by this map are considered by {@link #getNetPoints(Competitor, TimePoint)}.
|
||||
* Backs the {@link #getCarriedPoints(Competitor)} API with data. Can be used to prime this leaderboard with
|
||||
* aggregated results of races not tracked / displayed by this leaderboard in detail. The points provided by this
|
||||
* map are considered by {@link #getNetPoints(Competitor, TimePoint)}.
|
||||
*/
|
||||
private final Map<Competitor, Double> carriedPoints;
|
||||
|
||||
/**
|
||||
* A set that manages the difference between {@link #getCompetitors()} and {@link #getAllCompetitors()}. Access
|
||||
* is controlled by the {@link #suppressedCompetitorsLock} lock.
|
||||
* A set that manages the difference between {@link #getCompetitors()} and {@link #getAllCompetitors()}. Access is
|
||||
* controlled by the {@link #suppressedCompetitorsLock} lock.
|
||||
*/
|
||||
private final Set<Competitor> suppressedCompetitors;
|
||||
private final NamedReentrantReadWriteLock suppressedCompetitorsLock;
|
||||
@@ -107,8 +108,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
private final Fleet fleet;
|
||||
|
||||
private EntryImpl(Callable<Integer> trackedRankProvider, Double totalPoints,
|
||||
Callable<Double> totalPointsUncorrectedProvider, boolean isTotalPointsCorrected,
|
||||
Double netPoints, MaxPointsReason maxPointsReason, boolean discarded, Fleet fleet) {
|
||||
Callable<Double> totalPointsUncorrectedProvider, boolean isTotalPointsCorrected, Double netPoints,
|
||||
MaxPointsReason maxPointsReason, boolean discarded, Fleet fleet) {
|
||||
super();
|
||||
this.trackedRankProvider = trackedRankProvider;
|
||||
this.totalPoints = totalPoints;
|
||||
@@ -119,6 +120,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
this.discarded = discarded;
|
||||
this.fleet = fleet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTrackedRank() {
|
||||
try {
|
||||
@@ -127,30 +129,37 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getTotalPoints() {
|
||||
return totalPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTotalPointsCorrected() {
|
||||
return isTotalPointsCorrected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getNetPoints() {
|
||||
return netPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaxPointsReason getMaxPointsReason() {
|
||||
return maxPointsReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDiscarded() {
|
||||
return discarded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fleet getFleet() {
|
||||
return fleet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getTotalPointsUncorrected() {
|
||||
try {
|
||||
@@ -160,7 +169,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computing the competitors can be a bit expensive, particularly if the fleet is large and there may be suppressed
|
||||
* competitors, and the leaderboard may be a meta-leaderboard that refers to other leaderboards which each have
|
||||
@@ -171,10 +180,10 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
*
|
||||
* As it turns out, one of the most frequent uses of the {@link AbstractSimpleLeaderboardImpl#getCompetitors}
|
||||
* competitors list is to determine their number which in turn is only required for high-point scoring systems and
|
||||
* for computing the default score for penalties. Again, the most frequently used low-point family of scoring schemes
|
||||
* does not require this number. Yet, the scoring scheme requires an argument for polymorphic use by those that
|
||||
* need it. Instead of computing it for each call, this interface lets us defer the actual calculation until the
|
||||
* point when it's really needed. Once asked, this object will cache the result. Therefore, a new one should be
|
||||
* for computing the default score for penalties. Again, the most frequently used low-point family of scoring
|
||||
* schemes does not require this number. Yet, the scoring scheme requires an argument for polymorphic use by those
|
||||
* that need it. Instead of computing it for each call, this interface lets us defer the actual calculation until
|
||||
* the point when it's really needed. Once asked, this object will cache the result. Therefore, a new one should be
|
||||
* constructed each time the number shall be computed.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
@@ -183,7 +192,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
public class NumberOfCompetitorsFetcherImpl implements NumberOfCompetitorsInLeaderboardFetcher {
|
||||
private int numberOfCompetitors = -1;
|
||||
private int numberOfCompetitorsWithoutMaxPointReason = -1;
|
||||
|
||||
|
||||
@Override
|
||||
public int getNumberOfCompetitorsInLeaderboard() {
|
||||
if (numberOfCompetitors == -1) {
|
||||
@@ -191,7 +200,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
return numberOfCompetitors;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getNumberOfCompetitorsWithoutMaxPointReason(RaceColumn column, TimePoint timePoint) {
|
||||
if (numberOfCompetitorsWithoutMaxPointReason == -1) {
|
||||
@@ -215,17 +224,17 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
this.suppressedCompetitors = new HashSet<Competitor>();
|
||||
this.suppressedCompetitorsLock = new NamedReentrantReadWriteLock("suppressedCompetitorsLock", /* fair */ false);
|
||||
}
|
||||
|
||||
|
||||
protected RaceColumnListeners getRaceColumnListeners() {
|
||||
return raceColumnListeners;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
getRaceColumnListeners().notifyListenersAboutTrackedRaceUnlinked(raceColumn, fleet, trackedRace);
|
||||
super.trackedRaceUnlinked(raceColumn, fleet, trackedRace);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void trackedRaceLinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
getRaceColumnListeners().notifyListenersAboutTrackedRaceLinked(raceColumn, fleet, trackedRace);
|
||||
@@ -235,10 +244,11 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
public void isMedalRaceChanged(RaceColumn raceColumn, boolean newIsMedalRace) {
|
||||
getRaceColumnListeners().notifyListenersAboutIsMedalRaceChanged(raceColumn, newIsMedalRace);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void isFleetsCanRunInParallelChanged(RaceColumn raceColumn, boolean newIsFleetsCanRunInParallel) {
|
||||
getRaceColumnListeners().notifyListenersAboutIsFleetsCanRunInParallelChanged(raceColumn, newIsFleetsCanRunInParallel);
|
||||
getRaceColumnListeners().notifyListenersAboutIsFleetsCanRunInParallelChanged(raceColumn,
|
||||
newIsFleetsCanRunInParallel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,13 +257,16 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isFirstColumnIsNonDiscardableCarryForwardChanged(RaceColumn raceColumn, boolean firstColumnIsNonDiscardableCarryForward) {
|
||||
getRaceColumnListeners().notifyListenersAboutIsFirstColumnIsNonDiscardableCarryForwardChanged(raceColumn, firstColumnIsNonDiscardableCarryForward);
|
||||
public void isFirstColumnIsNonDiscardableCarryForwardChanged(RaceColumn raceColumn,
|
||||
boolean firstColumnIsNonDiscardableCarryForward) {
|
||||
getRaceColumnListeners().notifyListenersAboutIsFirstColumnIsNonDiscardableCarryForwardChanged(raceColumn,
|
||||
firstColumnIsNonDiscardableCarryForward);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasSplitFleetContiguousScoringChanged(RaceColumn raceColumn, boolean hasSplitFleetContiguousScoring) {
|
||||
getRaceColumnListeners().notifyListenersAboutHasSplitFleetContiguousScoringChanged(raceColumn, hasSplitFleetContiguousScoring);
|
||||
getRaceColumnListeners().notifyListenersAboutHasSplitFleetContiguousScoringChanged(raceColumn,
|
||||
hasSplitFleetContiguousScoring);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,11 +296,13 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
|
||||
@Override
|
||||
public void competitorDisplayNameChanged(Competitor competitor, String oldDisplayName, String displayName) {
|
||||
getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName, displayName);
|
||||
getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName,
|
||||
displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
|
||||
public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule,
|
||||
ResultDiscardingRule newDiscardingRule) {
|
||||
getRaceColumnListeners().notifyListenersAboutResultDiscardingRuleChanged(oldDiscardingRule, newDiscardingRule);
|
||||
}
|
||||
|
||||
@@ -304,7 +319,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
protected SettableScoreCorrection createScoreCorrection() {
|
||||
return new ScoreCorrectionImpl(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SettableScoreCorrection getScoreCorrection() {
|
||||
return scoreCorrection;
|
||||
@@ -372,7 +387,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
String oldDisplayName = displayNames.get(competitor);
|
||||
displayNames.put(competitor, displayName);
|
||||
if (!Util.equalsWithNull(oldDisplayName, displayName)) {
|
||||
getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName, displayName);
|
||||
getRaceColumnListeners().notifyListenersAboutCompetitorDisplayNameChanged(competitor, oldDisplayName,
|
||||
displayName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,9 +401,9 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
|
||||
@Override
|
||||
public Double getTotalPoints(final Competitor competitor, final RaceColumn raceColumn, final TimePoint timePoint) {
|
||||
return getScoreCorrection().getCorrectedScore(
|
||||
()->getTrackedRank(competitor, raceColumn, timePoint), competitor,
|
||||
raceColumn, this, timePoint, new NumberOfCompetitorsFetcherImpl(), getScoringScheme()).getCorrectedScore();
|
||||
return getScoreCorrection().getCorrectedScore(() -> getTrackedRank(competitor, raceColumn, timePoint),
|
||||
competitor, raceColumn, this, timePoint, new NumberOfCompetitorsFetcherImpl(), getScoringScheme())
|
||||
.getCorrectedScore();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -399,19 +415,19 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
public boolean isDiscarded(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) {
|
||||
return isDiscarded(competitor, raceColumn, getRaceColumns(), timePoint);
|
||||
}
|
||||
|
||||
|
||||
private boolean isDiscarded(Competitor competitor, RaceColumn raceColumn,
|
||||
Iterable<RaceColumn> raceColumnsToConsider, TimePoint timePoint) {
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule()
|
||||
.getDiscardedRaceColumns(competitor, this, raceColumnsToConsider, timePoint);
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this,
|
||||
raceColumnsToConsider, timePoint);
|
||||
return isDiscarded(competitor, raceColumn, timePoint, discardedRaceColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #isDiscarded(Competitor, RaceColumn, TimePoint)}, only that the set of discarded race columns can
|
||||
* be specified which is useful when net points are to be computed for more than one column for the same
|
||||
* competitor because then the calculation of discards (which requires looking at all columns) only needs to be done
|
||||
* once and not again for each column (which would lead to quadratic effort).
|
||||
* be specified which is useful when net points are to be computed for more than one column for the same competitor
|
||||
* because then the calculation of discards (which requires looking at all columns) only needs to be done once and
|
||||
* not again for each column (which would lead to quadratic effort).
|
||||
*
|
||||
* @param discardedRaceColumns
|
||||
* expected to be the result of what we would get if we called {@link #getResultDiscardingRule()}.
|
||||
@@ -420,8 +436,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
*/
|
||||
private boolean isDiscarded(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint,
|
||||
final Set<RaceColumn> discardedRaceColumns) {
|
||||
return !raceColumn.isMedalRace()
|
||||
&& getMaxPointsReason(competitor, raceColumn, timePoint).isDiscardable()
|
||||
return !raceColumn.isMedalRace() && getMaxPointsReason(competitor, raceColumn, timePoint).isDiscardable()
|
||||
&& discardedRaceColumns.contains(raceColumn);
|
||||
}
|
||||
|
||||
@@ -431,16 +446,16 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getNetPoints(Competitor competitor, RaceColumn raceColumn,
|
||||
Iterable<RaceColumn> raceColumnsToConsider, TimePoint timePoint) {
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule()
|
||||
.getDiscardedRaceColumns(competitor, this, raceColumnsToConsider, timePoint);
|
||||
public Double getNetPoints(Competitor competitor, RaceColumn raceColumn, Iterable<RaceColumn> raceColumnsToConsider,
|
||||
TimePoint timePoint) {
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this,
|
||||
raceColumnsToConsider, timePoint);
|
||||
return getNetPoints(competitor, raceColumn, timePoint, discardedRaceColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #getNetPoints(Competitor, RaceColumn, Iterable, TimePoint)}, only that the set of discarded race columns can
|
||||
* be specified which is useful when net points are to be computed for more than one column for the same
|
||||
* Same as {@link #getNetPoints(Competitor, RaceColumn, Iterable, TimePoint)}, only that the set of discarded race
|
||||
* columns can be specified which is useful when net points are to be computed for more than one column for the same
|
||||
* competitor because then the calculation of discards (which requires looking at all columns) only needs to be done
|
||||
* once and not again for each column (which would lead to quadratic effort).
|
||||
*
|
||||
@@ -450,7 +465,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
* getDiscardedRaceColumns(competitor, this, raceColumnsToConsider, timePoint)}.
|
||||
*/
|
||||
@Override
|
||||
public Double getNetPoints(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint, Set<RaceColumn> discardedRaceColumns) {
|
||||
public Double getNetPoints(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint,
|
||||
Set<RaceColumn> discardedRaceColumns) {
|
||||
Double result;
|
||||
if (isDiscarded(competitor, raceColumn, timePoint, discardedRaceColumns)) {
|
||||
result = 0.0;
|
||||
@@ -473,11 +489,12 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
@Override
|
||||
public Double getNetPoints(Competitor competitor, final Iterable<RaceColumn> raceColumnsToConsider,
|
||||
TimePoint timePoint) {
|
||||
// when a column with isStartsWithZeroScore() is found, only reset score if the competitor scored in any race from there on
|
||||
// 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);
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule()
|
||||
.getDiscardedRaceColumns(competitor, this, raceColumnsToConsider, timePoint);
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this,
|
||||
raceColumnsToConsider, timePoint);
|
||||
for (RaceColumn raceColumn : raceColumnsToConsider) {
|
||||
if (raceColumn.isStartsWithZeroScore()) {
|
||||
needToResetScoreUponNextNonEmptyEntry = true;
|
||||
@@ -497,16 +514,19 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
/**
|
||||
* All competitors with non-<code>null</code> total points are added to the result which is then sorted by total points in ascending
|
||||
* order. The fleet, if ordered, is the primary ordering criterion, followed by the total points.
|
||||
* All competitors with non-<code>null</code> total points are added to the result which is then sorted by total
|
||||
* points in ascending order. The fleet, if ordered, is the primary ordering criterion, followed by the total
|
||||
* points.
|
||||
*/
|
||||
@Override
|
||||
public List<Competitor> getCompetitorsFromBestToWorst(final RaceColumn raceColumn, TimePoint timePoint) throws NoWindException {
|
||||
public List<Competitor> getCompetitorsFromBestToWorst(final RaceColumn raceColumn, TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
final Map<Competitor, com.sap.sse.common.Util.Pair<Double, Fleet>> totalPointsAndFleet = new HashMap<Competitor, com.sap.sse.common.Util.Pair<Double, Fleet>>();
|
||||
for (Competitor competitor : getCompetitors()) {
|
||||
Double totalPoints = getTotalPoints(competitor, raceColumn, timePoint);
|
||||
if (totalPoints != null) {
|
||||
totalPointsAndFleet.put(competitor, new com.sap.sse.common.Util.Pair<Double, Fleet>(totalPoints, raceColumn.getFleetOfCompetitor(competitor)));
|
||||
totalPointsAndFleet.put(competitor, new com.sap.sse.common.Util.Pair<Double, Fleet>(totalPoints,
|
||||
raceColumn.getFleetOfCompetitor(competitor)));
|
||||
}
|
||||
}
|
||||
List<Competitor> result = new ArrayList<Competitor>(totalPointsAndFleet.keySet());
|
||||
@@ -518,7 +538,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
comparisonResult = 0;
|
||||
} else {
|
||||
if (raceColumn.hasSplitFleets() && !raceColumn.hasSplitFleetContiguousScoring()) {
|
||||
// only check fleets if there are more than one and the column is not to be contiguously scored even in case
|
||||
// only check fleets if there are more than one and the column is not to be contiguously scored
|
||||
// even in case
|
||||
// of split fleets
|
||||
final Fleet o1Fleet = totalPointsAndFleet.get(o1).getB();
|
||||
final Fleet o2Fleet = totalPointsAndFleet.get(o2).getB();
|
||||
@@ -537,13 +558,14 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// either there are no split fleets or the split isn't relevant for scoring as for ordered fleets
|
||||
// either there are no split fleets or the split isn't relevant for scoring as for ordered
|
||||
// fleets
|
||||
// the scoring runs contiguously from top to bottom
|
||||
comparisonResult = 0;
|
||||
}
|
||||
if (comparisonResult == 0) {
|
||||
comparisonResult = getScoringScheme().getScoreComparator(/* nullScoresAreBetter */ false).compare(
|
||||
totalPointsAndFleet.get(o1).getA(), totalPointsAndFleet.get(o2).getA());
|
||||
comparisonResult = getScoringScheme().getScoreComparator(/* nullScoresAreBetter */ false)
|
||||
.compare(totalPointsAndFleet.get(o1).getA(), totalPointsAndFleet.get(o2).getA());
|
||||
}
|
||||
}
|
||||
return comparisonResult;
|
||||
@@ -559,11 +581,12 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
public List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) {
|
||||
return getCompetitorsFromBestToWorst(getRaceColumns(), timePoint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* suppressed competitors are removed from the result
|
||||
*/
|
||||
private List<Competitor> getCompetitorsFromBestToWorst(Iterable<RaceColumn> raceColumnsToConsider, TimePoint timePoint) {
|
||||
private List<Competitor> getCompetitorsFromBestToWorst(Iterable<RaceColumn> raceColumnsToConsider,
|
||||
TimePoint timePoint) {
|
||||
List<Competitor> result = new ArrayList<Competitor>();
|
||||
for (Competitor competitor : getCompetitors()) {
|
||||
result.add(competitor);
|
||||
@@ -571,9 +594,11 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
Collections.sort(result, getTotalRankComparator(raceColumnsToConsider, timePoint));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Comparator<? super Competitor> getTotalRankComparator(Iterable<RaceColumn> raceColumnsToConsider, TimePoint timePoint) {
|
||||
return new LeaderboardTotalRankComparator(this, timePoint, getScoringScheme(), /* nullScoresAreBetter */ false, raceColumnsToConsider);
|
||||
|
||||
protected Comparator<? super Competitor> getTotalRankComparator(Iterable<RaceColumn> raceColumnsToConsider,
|
||||
TimePoint timePoint) {
|
||||
return new LeaderboardTotalRankComparator(this, timePoint, getScoringScheme(), /* nullScoresAreBetter */ false,
|
||||
raceColumnsToConsider);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -599,15 +624,16 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean countRaceForComparisonWithDiscardingThresholds(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) {
|
||||
public boolean countRaceForComparisonWithDiscardingThresholds(Competitor competitor, RaceColumn raceColumn,
|
||||
TimePoint timePoint) {
|
||||
TrackedRace trackedRaceForCompetitorInColumn;
|
||||
return getScoringScheme().isValidInNetScore(this, raceColumn, competitor, timePoint) &&
|
||||
(getScoreCorrection().isScoreCorrected(competitor, raceColumn, timePoint) ||
|
||||
((trackedRaceForCompetitorInColumn=raceColumn.getTrackedRace(competitor)) != null &&
|
||||
trackedRaceForCompetitorInColumn.hasStarted(timePoint) &&
|
||||
trackedRaceForCompetitorInColumn.getRank(competitor, timePoint) != 0));
|
||||
return getScoringScheme().isValidInNetScore(this, raceColumn, competitor, timePoint)
|
||||
&& (getScoreCorrection().isScoreCorrected(competitor, raceColumn, timePoint)
|
||||
|| ((trackedRaceForCompetitorInColumn = raceColumn.getTrackedRace(competitor)) != null
|
||||
&& trackedRaceForCompetitorInColumn.hasStarted(timePoint)
|
||||
&& trackedRaceForCompetitorInColumn.getRank(competitor, timePoint) != 0));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addRaceColumnListener(RaceColumnListener listener) {
|
||||
getRaceColumnListeners().addRaceColumnListener(listener);
|
||||
@@ -619,27 +645,31 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entry getEntry(final Competitor competitor, final RaceColumn race, final TimePoint timePoint) throws NoWindException {
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this, getRaceColumns(), timePoint);
|
||||
public Entry getEntry(final Competitor competitor, final RaceColumn race, final TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
final Set<RaceColumn> discardedRaceColumns = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this,
|
||||
getRaceColumns(), timePoint);
|
||||
return getEntry(competitor, race, timePoint, discardedRaceColumns);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Entry getEntry(final Competitor competitor, final RaceColumn race, final TimePoint timePoint,
|
||||
Set<RaceColumn> discardedRaceColumns) throws NoWindException {
|
||||
Callable<Integer> trackedRankProvider = ()->getTrackedRank(competitor, race, timePoint);
|
||||
Callable<Integer> trackedRankProvider = () -> getTrackedRank(competitor, race, timePoint);
|
||||
final Result correctedResults = getScoreCorrection().getCorrectedScore(trackedRankProvider, competitor, race,
|
||||
this, timePoint, new NumberOfCompetitorsFetcherImpl(), getScoringScheme());
|
||||
boolean discarded = isDiscarded(competitor, race, timePoint, discardedRaceColumns);
|
||||
final Double correctedScore = correctedResults.getCorrectedScore();
|
||||
return new EntryImpl(trackedRankProvider, correctedScore, ()->correctedResults.getUncorrectedScore(),
|
||||
correctedResults.isCorrected(), discarded ? DOUBLE_0 : correctedScore == null ? null
|
||||
: Double.valueOf(correctedScore * race.getFactor()), correctedResults.getMaxPointsReason(), discarded,
|
||||
race.getFleetOfCompetitor(competitor));
|
||||
return new EntryImpl(trackedRankProvider, correctedScore, () -> correctedResults.getUncorrectedScore(),
|
||||
correctedResults.isCorrected(),
|
||||
discarded ? DOUBLE_0
|
||||
: correctedScore == null ? null : Double.valueOf(correctedScore * race.getFactor()),
|
||||
correctedResults.getMaxPointsReason(), discarded, race.getFleetOfCompetitor(competitor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<RaceColumn, List<Competitor>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(TimePoint timePoint) throws NoWindException {
|
||||
public Map<RaceColumn, List<Competitor>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
Map<RaceColumn, List<Competitor>> result = new LinkedHashMap<>();
|
||||
List<RaceColumn> raceColumnsToConsider = new ArrayList<>();
|
||||
for (RaceColumn raceColumn : getRaceColumns()) {
|
||||
@@ -663,7 +693,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
public Map<Competitor, Double> call() {
|
||||
Map<Competitor, Double> netPointsSumPerCompetitorInColumn = new HashMap<>();
|
||||
for (Competitor competitor : getCompetitors()) {
|
||||
netPointsSumPerCompetitorInColumn.put(competitor, getNetPoints(competitor, finalRaceColumnsToConsider, timePoint));
|
||||
netPointsSumPerCompetitorInColumn.put(competitor,
|
||||
getNetPoints(competitor, finalRaceColumnsToConsider, timePoint));
|
||||
}
|
||||
synchronized (result) {
|
||||
return netPointsSumPerCompetitorInColumn;
|
||||
@@ -686,27 +717,29 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<com.sap.sse.common.Util.Pair<Competitor, RaceColumn>, Entry> getContent(final TimePoint timePoint) throws NoWindException {
|
||||
public Map<com.sap.sse.common.Util.Pair<Competitor, RaceColumn>, Entry> getContent(final TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
Map<com.sap.sse.common.Util.Pair<Competitor, RaceColumn>, Entry> result = new HashMap<com.sap.sse.common.Util.Pair<Competitor, RaceColumn>, Entry>();
|
||||
Map<Competitor, Set<RaceColumn>> discardedRaces = new HashMap<Competitor, Set<RaceColumn>>();
|
||||
for (final RaceColumn raceColumn : getRaceColumns()) {
|
||||
for (final Competitor competitor : getCompetitors()) {
|
||||
Callable<Integer> trackedRankProvider = ()->getTrackedRank(competitor, raceColumn, timePoint);
|
||||
final Result correctedResults = getScoreCorrection().getCorrectedScore(trackedRankProvider, competitor, raceColumn,
|
||||
this, timePoint, new NumberOfCompetitorsFetcherImpl(), getScoringScheme());
|
||||
Callable<Integer> trackedRankProvider = () -> getTrackedRank(competitor, raceColumn, timePoint);
|
||||
final Result correctedResults = getScoreCorrection().getCorrectedScore(trackedRankProvider, competitor,
|
||||
raceColumn, this, timePoint, new NumberOfCompetitorsFetcherImpl(), getScoringScheme());
|
||||
Set<RaceColumn> discardedRacesForCompetitor = discardedRaces.get(competitor);
|
||||
if (discardedRacesForCompetitor == null) {
|
||||
discardedRacesForCompetitor = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this, getRaceColumns(), timePoint);
|
||||
discardedRacesForCompetitor = getResultDiscardingRule().getDiscardedRaceColumns(competitor, this,
|
||||
getRaceColumns(), timePoint);
|
||||
discardedRaces.put(competitor, discardedRacesForCompetitor);
|
||||
}
|
||||
boolean discarded = discardedRacesForCompetitor.contains(raceColumn);
|
||||
final Double correctedScore = correctedResults.getCorrectedScore();
|
||||
Entry entry = new EntryImpl(trackedRankProvider, correctedScore,
|
||||
()->correctedResults.getUncorrectedScore(),
|
||||
correctedResults.isCorrected(),
|
||||
discarded ? DOUBLE_0 : (correctedScore==null?null:
|
||||
Double.valueOf((correctedScore * raceColumn.getFactor()))), correctedResults.getMaxPointsReason(),
|
||||
discarded, raceColumn.getFleetOfCompetitor(competitor));
|
||||
() -> correctedResults.getUncorrectedScore(), correctedResults.isCorrected(),
|
||||
discarded ? DOUBLE_0
|
||||
: (correctedScore == null ? null
|
||||
: Double.valueOf((correctedScore * raceColumn.getFactor()))),
|
||||
correctedResults.getMaxPointsReason(), discarded, raceColumn.getFleetOfCompetitor(competitor));
|
||||
result.put(new com.sap.sse.common.Util.Pair<Competitor, RaceColumn>(competitor, raceColumn), entry);
|
||||
}
|
||||
}
|
||||
@@ -714,7 +747,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
/**
|
||||
* A leaderboard will only accept the addition of a race column if the column's name is unique across the leaderboard.
|
||||
* A leaderboard will only accept the addition of a race column if the column's name is unique across the
|
||||
* leaderboard.
|
||||
*/
|
||||
@Override
|
||||
public boolean canAddRaceColumnToContainer(RaceColumn newRaceColumn) {
|
||||
@@ -731,17 +765,18 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
/**
|
||||
* Finds out the time point when any of the {@link Leaderboard#getTrackedRaces() tracked races currently attached to
|
||||
* the <code>leaderboard</code>} and the {@link Leaderboard#getScoreCorrection() score corrections} have last been
|
||||
* modified. If no tracked race is attached and no time-stamped score corrections have been applied to the leaderboard,
|
||||
* <code>null</code> is returned. The time point computed this way is a good choice for normalizing queries for later time
|
||||
* points in an attempt to achieve more cache hits.<p>
|
||||
* modified. If no tracked race is attached and no time-stamped score corrections have been applied to the
|
||||
* leaderboard, <code>null</code> is returned. The time point computed this way is a good choice for normalizing
|
||||
* queries for later time points in an attempt to achieve more cache hits.
|
||||
* <p>
|
||||
*
|
||||
* Note, however, that the result does not tell about structural changes to the leaderboard and therefore cannot be used
|
||||
* to determine the need for cache invalidation. For example, if a column is added to a leaderboard after the time point
|
||||
* returned by this method but that column's attached tracked race has finished before the time point returned by this method,
|
||||
* the result of this method won't change. Still, the contents of the leaderboard will change by a change in column structure.
|
||||
* A different means to determine the possibility of changes that happened to this leaderboard must be used for cache
|
||||
* management. Such a facility has to listen for score correction changes, tracked races being attached or detached and
|
||||
* the column structure changing.
|
||||
* Note, however, that the result does not tell about structural changes to the leaderboard and therefore cannot be
|
||||
* used to determine the need for cache invalidation. For example, if a column is added to a leaderboard after the
|
||||
* time point returned by this method but that column's attached tracked race has finished before the time point
|
||||
* returned by this method, the result of this method won't change. Still, the contents of the leaderboard will
|
||||
* change by a change in column structure. A different means to determine the possibility of changes that happened
|
||||
* to this leaderboard must be used for cache management. Such a facility has to listen for score correction
|
||||
* changes, tracked races being attached or detached and the column structure changing.
|
||||
*
|
||||
* @see TrackedRace#getTimePointOfNewestEvent()
|
||||
* @see SettableScoreCorrection#getTimePointOfLastCorrectionsValidity()
|
||||
@@ -750,19 +785,22 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
public TimePoint getTimePointOfLatestModification() {
|
||||
TimePoint result = null;
|
||||
for (TrackedRace trackedRace : getTrackedRaces()) {
|
||||
if (result == null || (trackedRace.getTimePointOfNewestEvent() != null && trackedRace.getTimePointOfNewestEvent().after(result))) {
|
||||
if (result == null || (trackedRace.getTimePointOfNewestEvent() != null
|
||||
&& trackedRace.getTimePointOfNewestEvent().after(result))) {
|
||||
result = trackedRace.getTimePointOfNewestEvent();
|
||||
}
|
||||
}
|
||||
TimePoint timePointOfLastScoreCorrection = getScoreCorrection().getTimePointOfLastCorrectionsValidity();
|
||||
if (timePointOfLastScoreCorrection != null && (result == null || timePointOfLastScoreCorrection.after(result))) {
|
||||
if (timePointOfLastScoreCorrection != null
|
||||
&& (result == null || timePointOfLastScoreCorrection.after(result))) {
|
||||
result = timePointOfLastScoreCorrection;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sap.sse.common.Util.Pair<GPSFixMoving, Speed> getMaximumSpeedOverGround(Competitor competitor, TimePoint timePoint) {
|
||||
public com.sap.sse.common.Util.Pair<GPSFixMoving, Speed> getMaximumSpeedOverGround(Competitor competitor,
|
||||
TimePoint timePoint) {
|
||||
com.sap.sse.common.Util.Pair<GPSFixMoving, Speed> result = null;
|
||||
// TODO should we ensure that competitor participated in all race columns?
|
||||
for (TrackedRace trackedRace : getTrackedRaces()) {
|
||||
@@ -771,16 +809,17 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
if (!markPassings.isEmpty()) {
|
||||
TimePoint from = markPassings.first().getTimePoint();
|
||||
TimePoint to;
|
||||
if (timePoint.after(markPassings.last().getTimePoint()) &&
|
||||
markPassings.last().getWaypoint() == trackedRace.getRace().getCourse().getLastWaypoint()) {
|
||||
if (timePoint.after(markPassings.last().getTimePoint()) && markPassings.last()
|
||||
.getWaypoint() == trackedRace.getRace().getCourse().getLastWaypoint()) {
|
||||
// stop counting when competitor finished the race
|
||||
to = markPassings.last().getTimePoint();
|
||||
} else {
|
||||
to = timePoint;
|
||||
}
|
||||
com.sap.sse.common.Util.Pair<GPSFixMoving, Speed> maxSpeed = trackedRace.getTrack(competitor).getMaximumSpeedOverGround(from, to);
|
||||
if (result == null || result.getB() == null ||
|
||||
(maxSpeed != null && maxSpeed.getB() != null && maxSpeed.getB().compareTo(result.getB()) > 0)) {
|
||||
com.sap.sse.common.Util.Pair<GPSFixMoving, Speed> maxSpeed = trackedRace.getTrack(competitor)
|
||||
.getMaximumSpeedOverGround(from, to);
|
||||
if (result == null || result.getB() == null || (maxSpeed != null && maxSpeed.getB() != null
|
||||
&& maxSpeed.getB().compareTo(result.getB()) > 0)) {
|
||||
result = maxSpeed;
|
||||
}
|
||||
}
|
||||
@@ -799,7 +838,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors() {
|
||||
final Iterable<Competitor> result;
|
||||
@@ -815,10 +854,11 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors(RaceColumn raceColumn, Fleet fleet) {
|
||||
return getCompetitorIterableSkippingSuppressed(getAllCompetitors(raceColumn, fleet), getSuppressedCompetitors());
|
||||
return getCompetitorIterableSkippingSuppressed(getAllCompetitors(raceColumn, fleet),
|
||||
getSuppressedCompetitors());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -838,7 +878,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
LockUtil.unlockAfterRead(suppressedCompetitorsLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSuppressed(Competitor competitor) {
|
||||
LockUtil.lockForRead(suppressedCompetitorsLock);
|
||||
@@ -848,12 +888,12 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
LockUtil.unlockAfterRead(suppressedCompetitorsLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSuppressed(Competitor competitor, boolean suppressed) {
|
||||
if (competitor == null) {
|
||||
throw new IllegalArgumentException("Cannot change suppression for a null competitor");
|
||||
}
|
||||
if (competitor == null) {
|
||||
throw new IllegalArgumentException("Cannot change suppression for a null competitor");
|
||||
}
|
||||
LockUtil.lockForWrite(suppressedCompetitorsLock);
|
||||
try {
|
||||
if (suppressed) {
|
||||
@@ -874,7 +914,7 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
TimePoint timePoint = delayToLiveInMillis == null ? now : now.minus(delayToLiveInMillis);
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void raceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier, RaceLogEvent event) {
|
||||
getRaceColumnListeners().notifyListenersAboutRaceLogEventAdded(raceColumn, raceLogIdentifier, event);
|
||||
@@ -887,14 +927,16 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " " + (getDefaultCourseArea() != null ? getDefaultCourseArea().getName() : "<No course area defined>") + " " + (getScoringScheme() != null ? getScoringScheme().getType().name() : "<No scoring scheme set>");
|
||||
return getName() + " "
|
||||
+ (getDefaultCourseArea() != null ? getDefaultCourseArea().getName() : "<No course area defined>") + " "
|
||||
+ (getScoringScheme() != null ? getScoringScheme().getType().name() : "<No scoring scheme set>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberOfCompetitorsInLeaderboardFetcher getNumberOfCompetitorsInLeaderboardFetcher() {
|
||||
return new NumberOfCompetitorsFetcherImpl();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Pair<RaceColumn, Fleet> getRaceColumnAndFleet(TrackedRace trackedRace) {
|
||||
for (final RaceColumn raceColumn : getRaceColumns()) {
|
||||
@@ -914,8 +956,8 @@ public abstract class AbstractSimpleLeaderboardImpl extends AbstractLeaderboardW
|
||||
Map<Competitor, Boat> competitorsAndTheirBoats = raceColumn.getAllCompetitorsAndTheirBoats();
|
||||
allBoats.addAll(competitorsAndTheirBoats.values());
|
||||
}
|
||||
return Util.getDominantObject(StreamSupport.stream(allBoats.spliterator(), /* parallel */ false).
|
||||
map(b->b.getBoatClass()).collect(Collectors.toList()));
|
||||
return Util.getDominantObject(StreamSupport.stream(allBoats.spliterator(), /* parallel */ false)
|
||||
.map(b -> b.getBoatClass()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
}
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
package com.sap.sailing.domain.racelog.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceCompetitorMappingFinder;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMarkMappingFinder;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* At the moment, the timerange covered by the fixes for a device, and the number of fixes for a device are stored in a
|
||||
* metadata collection. Should be changed, see bug 1982.
|
||||
*
|
||||
* @author Fredrik Teschke
|
||||
*/
|
||||
public class GPSFixStoreImpl implements GPSFixStore {
|
||||
private final SensorFixStore sensorFixStore;
|
||||
|
||||
public GPSFixStoreImpl(SensorFixStore sensorFixStore) {
|
||||
this.sensorFixStore = sensorFixStore;
|
||||
}
|
||||
|
||||
private <FixT extends GPSFix> void loadTrack(DynamicGPSFixTrack<?, FixT> track, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to, boolean toIsInclusive)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
loadTrack(track, device, from, to, toIsInclusive, () -> {
|
||||
return false;
|
||||
}, (c) -> {
|
||||
});
|
||||
}
|
||||
|
||||
private <FixT extends GPSFix> void loadTrack(DynamicGPSFixTrack<?, FixT> track, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to, boolean toIsInclusive, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progress)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
sensorFixStore.<FixT> loadFixes(fix -> track.add(fix, /* replace */ true), device, from, to, toIsInclusive,
|
||||
isPreemptiveStopped, progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RegattaLog log,
|
||||
Competitor competitor) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
List<DeviceMappingWithRegattaLogEvent<Competitor>> mappings = new RegattaLogDeviceCompetitorMappingFinder(log)
|
||||
.analyze().get(competitor);
|
||||
if (mappings != null) {
|
||||
for (DeviceMapping<Competitor> mapping : mappings) {
|
||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(),
|
||||
false /* toIsInclusive */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark)
|
||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||
List<DeviceMappingWithRegattaLogEvent<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze()
|
||||
.get(mark);
|
||||
if (mappings != null) {
|
||||
for (DeviceMapping<Mark> mapping : mappings) {
|
||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(),
|
||||
false /* toIsInclusive */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeFix(DeviceIdentifier device, GPSFix fix) {
|
||||
sensorFixStore.storeFix(device, fix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track,
|
||||
DeviceMapping<Competitor> mapping, TimePoint start, TimePoint end, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
|
||||
// loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true
|
||||
// /*inclusive*/);
|
||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||
loadTrack(track, mapping.getDevice(), from, to, true /* inclusive */, isPreemptiveStopped, progressReporter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping, TimePoint start,
|
||||
TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReport)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||
loadTrack(track, mapping.getDevice(), from, to, true /* inclusive */, isPreemptiveStopped, progressReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark, TimePoint start,
|
||||
TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
List<DeviceMappingWithRegattaLogEvent<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze()
|
||||
.get(mark);
|
||||
if (mappings != null) {
|
||||
for (DeviceMapping<Mark> mapping : mappings) {
|
||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||
loadTrack(track, mapping.getDevice(), from, to, false /* toIsInclusive */);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
package com.sap.sailing.domain.racelog.tracking;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public enum EmptyGPSFixStore implements GPSFixStore {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public void storeFix(DeviceIdentifier device, GPSFix fix) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track,
|
||||
RegattaLog log, Competitor competitor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track,
|
||||
RegattaLog log, Mark mark) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark,
|
||||
TimePoint start, TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track,
|
||||
DeviceMapping<Competitor> mapping, TimePoint start, TimePoint end, BooleanSupplier isPreemptiveStopped,
|
||||
Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping, TimePoint start,
|
||||
TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package com.sap.sailing.domain.racelog.tracking;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
|
||||
public interface GPSFixStore {
|
||||
/**
|
||||
* Load all fixes that correspond to the {@link RegattaLogDeviceCompetitorMappingEvent}s found in the {@code raceLog}.
|
||||
*/
|
||||
void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RegattaLog log,
|
||||
Competitor competitor) throws TransformationException;
|
||||
|
||||
/**
|
||||
* Load all fixes that correspond to the {@link RegattaLogDeviceMarkMappingEvent}s found in the {@code raceLog}.
|
||||
*/
|
||||
void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark) throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException;
|
||||
|
||||
/**
|
||||
* Load all fixes within the start and end time point (inclusive) that correspond to the
|
||||
* {@link RegattaLogDeviceMarkMappingEvent}s found in the {@code raceLog}.
|
||||
*
|
||||
* @param start
|
||||
* if <code>null</code>, the start of the time range for which to load fixes is only constrained by the
|
||||
* device mapping intervals
|
||||
* @param end
|
||||
* if <code>null</code>, the end of the time range for which to load fixes is only constrained by the
|
||||
* device mapping intervals
|
||||
*/
|
||||
void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark, TimePoint start,
|
||||
TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException;
|
||||
|
||||
void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, DeviceMapping<Competitor> mapping,
|
||||
TimePoint start, TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReporter)
|
||||
throws TransformationException, NoCorrespondingServiceRegisteredException;
|
||||
|
||||
/**
|
||||
* Load all fixes that correspond to the {@code mapping}.
|
||||
*/
|
||||
void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping, TimePoint start,
|
||||
TimePoint end, BooleanSupplier isPreemptiveStopped, Consumer<Double> progressReport)
|
||||
throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException;
|
||||
|
||||
void storeFix(DeviceIdentifier device, GPSFix fix) throws TransformationException, NoCorrespondingServiceRegisteredException;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.sap.sailing.domain.sharding;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LiveLeaderboardUpdater;
|
||||
|
||||
/**
|
||||
* The sharding context is used to store and verify contraints for a thread.
|
||||
*
|
||||
* This is currently used to verify if a given thread, that is explicitly expected to only
|
||||
* trigger the calculation of a given leaderboard, does trigger the calculation of further/ other
|
||||
* leaderboards.
|
||||
*
|
||||
* It is also used to log warnings if a leaderboard is calculated without predefining the thread constraint.
|
||||
*
|
||||
* The enum {@link ShardingType} lists the known sharding types. Each sharding type defines a prefix that will
|
||||
* be used to identify the sharding type from the request, as implemented in {@link #identifyAndSetShardingConstraint(String)}.
|
||||
*
|
||||
* By calling {@link #setShardingConstraint(ShardingType, String)} it is possible to directly set a thread constraint.
|
||||
* This is useful in background computing code, as in {@link LiveLeaderboardUpdater}
|
||||
*
|
||||
*/
|
||||
public class ShardingContext {
|
||||
private static final Logger logger = Logger.getLogger(ShardingContext.class.getName());
|
||||
|
||||
private static final ConcurrentMap<ShardingType, ThreadLocal<String>> shardingMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Sets the sharding context. The type of sharding will be identified by the prefix.
|
||||
*
|
||||
* @param shardingInfo
|
||||
*/
|
||||
public static ShardingType identifyAndSetShardingConstraint(String shardingInfo) {
|
||||
if (shardingInfo == null || shardingInfo.isEmpty()) {
|
||||
logger.warning("Empty sharding constraint");
|
||||
return null;
|
||||
}
|
||||
ThreadLocal<String> identifiedShardingHolder = null;
|
||||
for (ShardingType shardingType : ShardingType.values()) {
|
||||
if (shardingInfo.startsWith(shardingType.getPrefix())) {
|
||||
identifiedShardingHolder = shardingMap.computeIfAbsent(shardingType, t -> new ThreadLocal<>());
|
||||
checkAndSetShardingInfo(shardingType, shardingInfo, identifiedShardingHolder);
|
||||
return shardingType;
|
||||
}
|
||||
}
|
||||
if (identifiedShardingHolder == null) {
|
||||
logger.warning("Could not identify sharding type for: " + shardingInfo);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide sharding constraint for given sharding type.
|
||||
*
|
||||
* @param shardingType
|
||||
* @param shardingInfo
|
||||
*/
|
||||
public static void setShardingConstraint(ShardingType shardingType, String shardingInfo) {
|
||||
final String encodedShardingInfo = shardingType.encodeIfNeeded(shardingInfo);
|
||||
ThreadLocal<String> shardingHolder = shardingMap.computeIfAbsent(shardingType, t -> new ThreadLocal<>());
|
||||
checkAndSetShardingInfo(shardingType, encodedShardingInfo, shardingHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if provided sharding information name equals shard constraint.
|
||||
*
|
||||
* If the information is null or empty, we log a warning.
|
||||
* If shard does not have a constraint, we log a warning. If
|
||||
* the information provided does not match information previously stored in shard,
|
||||
* we make a severe log entry.
|
||||
*
|
||||
* @param shardingInfo
|
||||
*/
|
||||
public static void checkConstraint(final ShardingType type, final String shardingInfo) {
|
||||
if (shardingInfo == null || shardingInfo.isEmpty()) {
|
||||
logger.severe("Empty sharding constraint");
|
||||
return;
|
||||
}
|
||||
final ThreadLocal<String> shardingHolder = shardingMap.get(type);
|
||||
if (shardingHolder == null) {
|
||||
logger.log(Level.SEVERE, "No current sharding context set for " + type.name(), new RuntimeException());
|
||||
return;
|
||||
}
|
||||
String currentShardingInfo = shardingHolder.get();
|
||||
if (currentShardingInfo == null || currentShardingInfo.isEmpty()) {
|
||||
logger.warning("No current sharding constraint for " + type.name());
|
||||
return;
|
||||
}
|
||||
final String encodedShardingInfo = type.encodeIfNeeded(shardingInfo);
|
||||
if (!encodedShardingInfo.equals(currentShardingInfo)) {
|
||||
logger.log(Level.SEVERE, "Current sharding constraint vialation for " + type.name() + ". Got "
|
||||
+ shardingInfo + ", shard requires " + currentShardingInfo, new RuntimeException());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearShardingConstraint(ShardingType type) {
|
||||
ThreadLocal<String> shardingHolder = shardingMap.remove(type);
|
||||
if (shardingHolder != null) {
|
||||
shardingHolder.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkAndSetShardingInfo(ShardingType shardingType, String encodedShardingInfo,
|
||||
ThreadLocal<String> shardingHolder) {
|
||||
if (encodedShardingInfo == null || encodedShardingInfo.isEmpty()) {
|
||||
logger.log(Level.SEVERE, "Cannot set empty sharding information for " + shardingType.name(),
|
||||
new RuntimeException());
|
||||
}
|
||||
String currentShardingInfo = shardingHolder.get();
|
||||
if (currentShardingInfo == null) {
|
||||
shardingHolder.set(encodedShardingInfo);
|
||||
} else if (!encodedShardingInfo.equals(currentShardingInfo)) {
|
||||
logger.log(Level.SEVERE, "Switching shard constraint for " + shardingType.name()+". Got <<" + encodedShardingInfo +">>, expeted <<"+ currentShardingInfo+">>", new RuntimeException());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuse
|
||||
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.impl.NonCachingMarkPositionAtTimePointCache;
|
||||
@@ -773,7 +773,7 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
void waitUntilLoadingFromWindStoreComplete() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Whenever a {@link RegattaLog} is attached, fixes are loaded from the {@link GPSFixStore} for all mappings
|
||||
* Whenever a {@link RegattaLog} is attached, fixes are loaded from the {@link SensorFixStore} for all mappings
|
||||
* found in the {@code RegattaLog} in a separate thread. This method blocks if there is such a thread loading
|
||||
* fixes, until that thread is finished.
|
||||
*/
|
||||
@@ -812,19 +812,19 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
|
||||
/**
|
||||
* Attaches the passed race log with this {@link TrackedRace}.
|
||||
* This causes fixes from the {@link GPSFixStore} to be loaded for such {@link RegattaLogDeviceMappingEvent}s
|
||||
* that are present in the raceLog. This loading is offloaded into a separate thread, that blocks
|
||||
* This causes fixes from the {@link SensorFixStore} to be loaded for such {@link RegattaLogDeviceMappingEvent RegattaLogDeviceMappingEvents}
|
||||
* that are present in the {@link RaceLog raceLog}. This loading is offloaded into a separate thread, that blocks
|
||||
* serialization until it is finished. If multiple race logs are attached, the loading process is
|
||||
* forced to be serialized.
|
||||
* To garuantee that a the fixes for a race log have been fully loaded before continuing,
|
||||
* {@link #waitForLoadingFromGPSFixStoreToFinishRunning} can be used.
|
||||
* To guarantee that a the fixes for a race log have been fully loaded before continuing,
|
||||
* {@link #waitForLoadingToFinish()} can be used.
|
||||
* @param raceLog to be attached.
|
||||
*/
|
||||
void attachRaceLog(RaceLog raceLog);
|
||||
|
||||
/**
|
||||
* Attaches the passed regatta log with this {@link TrackedRace}.
|
||||
* This also causes fixes from the {@link GPSFixStore} to be loaded (see {@link #attachRaceLog} for details).
|
||||
* Attaches the passed {@link RegattaLog} with this {@link TrackedRace}.
|
||||
* This also causes fixes from the {@link SensorFixStore} to be loaded (see {@link #attachRaceLog(RaceLog)} for details).
|
||||
*/
|
||||
void attachRegattaLog(RegattaLog regattaLog);
|
||||
|
||||
@@ -846,7 +846,7 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
RaceLog getRaceLog(Serializable identifier);
|
||||
|
||||
/**
|
||||
* A setter for the listener on course design changes suggested by one of the {@link RaceLog}s attached to this
|
||||
* A setter for the listener on course design changes suggested by one of the {@link RaceLog RaceLog} attached to this
|
||||
* race. The listener is mostly part of the tracking provider adapter.
|
||||
*
|
||||
* @param listener
|
||||
|
||||
@@ -77,6 +77,7 @@ TrackLifecycle: true
|
||||
Export-Package: com.google.gwt.user.client.rpc.core.com.sap.sailing.domain.common.confidence.impl,
|
||||
com.google.gwt.user.client.rpc.core.com.sap.sailing.domain.common.impl,
|
||||
com.google.gwt.user.client.rpc.core.com.sap.sailing.domain.common.tracking.impl,
|
||||
com.sap.sailing.gwt.common.communication.routing,
|
||||
com.sap.sailing.gwt.home.communication,
|
||||
com.sap.sailing.gwt.home.server,
|
||||
com.sap.sailing.gwt.server,
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
<servlet-mapping>
|
||||
<servlet-name>SailingService</servlet-name>
|
||||
<url-pattern>/service/sailing</url-pattern>
|
||||
<url-pattern>/service/sailing/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
@@ -90,6 +91,7 @@
|
||||
<servlet-mapping>
|
||||
<servlet-name>sailingDispatch</servlet-name>
|
||||
<url-pattern>/service/dispatch</url-pattern>
|
||||
<url-pattern>/service/dispatch/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
|
||||
+25
-2
@@ -1,16 +1,20 @@
|
||||
package com.sap.sailing.gwt.autoplay.client.app;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.place.shared.Place;
|
||||
import com.google.gwt.place.shared.PlaceController;
|
||||
import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.google.web.bindery.event.shared.EventBus;
|
||||
import com.sap.sailing.gwt.autoplay.client.places.autoplaystart.AutoPlayStartPlace;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.ui.client.MediaService;
|
||||
import com.sap.sailing.gwt.ui.client.MediaServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.RemoteServiceMappingConstants;
|
||||
import com.sap.sailing.gwt.ui.client.SailingService;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceHelper;
|
||||
import com.sap.sse.gwt.client.EntryPointHelper;
|
||||
import com.sap.sse.security.ui.client.SecureClientFactoryImpl;
|
||||
|
||||
@@ -20,11 +24,13 @@ public abstract class AutoPlayClientFactoryBase
|
||||
private final MediaServiceAsync mediaService;
|
||||
private final AutoPlayPlaceNavigator navigator;
|
||||
|
||||
private final Map<String, SailingServiceAsync> services = new HashMap<>();
|
||||
|
||||
public AutoPlayClientFactoryBase(ApplicationTopLevelView root, EventBus eventBus, PlaceController placeController,
|
||||
AutoPlayPlaceNavigator navigator) {
|
||||
super(root, eventBus, placeController);
|
||||
this.navigator = navigator;
|
||||
sailingService = GWT.create(SailingService.class);
|
||||
sailingService = SailingServiceHelper.createSailingServiceInstance();
|
||||
mediaService = GWT.create(MediaService.class);
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) sailingService,
|
||||
RemoteServiceMappingConstants.sailingServiceRemotePath);
|
||||
@@ -39,8 +45,25 @@ public abstract class AutoPlayClientFactoryBase
|
||||
|
||||
@Override
|
||||
public SailingServiceAsync getSailingService() {
|
||||
if (isConfigured()) {
|
||||
return getSailingService(() -> getAutoPlayCtxSignalError().getContextDefinition().getLeaderboardName());
|
||||
}
|
||||
return sailingService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SailingServiceAsync getSailingService(ProvidesLeaderboardRouting routingProvider) {
|
||||
if (routingProvider == null) {
|
||||
return sailingService;
|
||||
} else {
|
||||
SailingServiceAsync sailingServiceAsync = services.get(routingProvider.routingSuffixPath());
|
||||
if (sailingServiceAsync == null) {
|
||||
sailingServiceAsync = SailingServiceHelper.createSailingServiceInstance(routingProvider);
|
||||
services.put(routingProvider.routingSuffixPath(), sailingServiceAsync);
|
||||
}
|
||||
return sailingServiceAsync;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaServiceAsync getMediaService() {
|
||||
|
||||
+17
-6
@@ -1,10 +1,13 @@
|
||||
package com.sap.sailing.gwt.autoplay.client.configs;
|
||||
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sailing.gwt.autoplay.client.app.AutoPlayClientFactory;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.gwt.settings.UrlBuilderUtil;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
public abstract class AutoPlayConfiguration {
|
||||
@@ -19,20 +22,28 @@ public abstract class AutoPlayConfiguration {
|
||||
OnSettingsCallback holder, PerspectiveCompositeSettings<?> settings, AutoPlayContextDefinition apcd,
|
||||
UserService userService) {
|
||||
Window.alert("This configuration does not have settings");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be pure/standalone, it is not allowed to make any guesses on fields written by startRootNode,
|
||||
* as it can be called before that
|
||||
*/
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, StrippedLeaderboardDTO leaderboard, UserService userService,
|
||||
OnSettingsCallback holder) {
|
||||
holder.newSettings(null);
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, AutoPlayContextDefinition apcd,
|
||||
StrippedLeaderboardDTO leaderboard, UserService userService, OnSettingsCallback holder) {
|
||||
holder.newSettings(null, getUrlWithSettings(apcd, null));
|
||||
}
|
||||
|
||||
private String getUrlWithSettings(AutoPlayContextDefinition apcd, PerspectiveCompositeSettings<?> settings) {
|
||||
UrlBuilder urlBuilder = UrlBuilderUtil.createUrlBuilderFromCurrentLocationWithCleanParameters();
|
||||
SettingsToUrlSerializer urlSerializer = new SettingsToUrlSerializer();
|
||||
if (settings != null) {
|
||||
urlSerializer.serializeSettingsMapToUrlBuilder(settings, urlBuilder);
|
||||
}
|
||||
urlSerializer.serializeToUrlBuilder(apcd, urlBuilder);
|
||||
return urlBuilder.buildString();
|
||||
}
|
||||
|
||||
public interface OnSettingsCallback {
|
||||
void newSettings(PerspectiveCompositeSettings<?> newSettings);
|
||||
void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings);
|
||||
}
|
||||
|
||||
}
|
||||
+55
-32
@@ -26,58 +26,81 @@ import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
public class AutoPlayClassicConfiguration extends AutoPlayConfiguration {
|
||||
private static final Logger logger = Logger.getLogger(AutoPlayClassicConfiguration.class.getName());
|
||||
|
||||
|
||||
@Override
|
||||
public void startRootNode(AutoPlayClientFactory cf, AutoPlayContextDefinition context,
|
||||
PerspectiveCompositeSettings<?> settings, EventDTO initialEventData) {
|
||||
cf.getSailingService().getAvailableDetailTypesForLeaderboard(context.getLeaderboardName(), new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
logger.log(Level.WARNING, "Could not load detailtypes for leaderboard", caught);
|
||||
}
|
||||
cf.getSailingService().getAvailableDetailTypesForLeaderboard(context.getLeaderboardName(),
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
logger.log(Level.WARNING, "Could not load detailtypes for leaderboard", caught);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
StrippedLeaderboardDTO leaderBoardDTO = AutoplayHelper.getSelectedLeaderboard(initialEventData,
|
||||
context.getLeaderboardName());
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderBoardDTO, cf.getUserService(), result);
|
||||
cf.setAutoPlayContext(new AutoPlayContextImpl(autoplayLifecycle,
|
||||
(PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>) settings,
|
||||
AutoPlayClassicConfiguration.this, context, initialEventData));
|
||||
// start sixty inch slide loop nodes...
|
||||
RootNodeClassic root = new RootNodeClassic(cf);
|
||||
root.start(cf.getEventBus());
|
||||
}
|
||||
});
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
StrippedLeaderboardDTO leaderBoardDTO = AutoplayHelper.getSelectedLeaderboard(initialEventData,
|
||||
context.getLeaderboardName());
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(
|
||||
leaderBoardDTO, cf.getUserService(), result);
|
||||
cf.setAutoPlayContext(new AutoPlayContextImpl(autoplayLifecycle,
|
||||
(PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>) settings,
|
||||
AutoPlayClassicConfiguration.this, context, initialEventData));
|
||||
// start sixty inch slide loop nodes...
|
||||
RootNodeClassic root = new RootNodeClassic(cf);
|
||||
root.start(cf.getEventBus());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openSettingsDialog(EventDTO selectedEvent, StrippedLeaderboardDTO leaderboard,
|
||||
OnSettingsCallback settingsCallback, PerspectiveCompositeSettings<?> settings, AutoPlayContextDefinition apcd, UserService userService) {
|
||||
OnSettingsCallback settingsCallback, PerspectiveCompositeSettings<?> settings,
|
||||
AutoPlayContextDefinition apcd, UserService userService) {
|
||||
DialogCallback<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> callback = new DialogCallback<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>>() {
|
||||
@Override
|
||||
public void ok(PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> editedObject) {
|
||||
settingsCallback.newSettings(editedObject);
|
||||
settingsCallback.newSettings(editedObject,
|
||||
getUrlWithSettings(apcd, editedObject, leaderboard, userService));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
};
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService, Arrays.asList(DetailType.values()));
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> autoplayPerspectiveSettings = autoplayLifecycle
|
||||
.createDefaultSettings();
|
||||
LinkWithSettingsGenerator<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> settingsGenerator = new LinkWithSettingsGenerator<>(Window.Location.getPath(), autoplayLifecycle::createDefaultSettings, apcd);
|
||||
new SettingsDialogForLinkSharing<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>>(settingsGenerator,
|
||||
autoplayLifecycle, autoplayPerspectiveSettings, StringMessages.INSTANCE, true, callback).show();
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService,
|
||||
Arrays.asList(DetailType.values()));
|
||||
@SuppressWarnings("unchecked")
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> autoplayPerspectiveSettings = settings != null
|
||||
? (PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>) settings
|
||||
: autoplayLifecycle.createDefaultSettings();
|
||||
LinkWithSettingsGenerator<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> settingsGenerator = new LinkWithSettingsGenerator<>(
|
||||
Window.Location.getPath(), autoplayLifecycle::createDefaultSettings, apcd);
|
||||
new SettingsDialogForLinkSharing<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>>(
|
||||
settingsGenerator, autoplayLifecycle, autoplayPerspectiveSettings, StringMessages.INSTANCE, true,
|
||||
callback).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, StrippedLeaderboardDTO leaderboard,
|
||||
UserService userService, OnSettingsCallback settingsCallback) {
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService, Arrays.asList(DetailType.values()));
|
||||
settingsCallback.newSettings(autoplayLifecycle.createDefaultSettings());
|
||||
public void loadSettingsDefault(EventDTO selectedEvent, AutoPlayContextDefinition apcd,
|
||||
StrippedLeaderboardDTO leaderboard, UserService userService, OnSettingsCallback settingsCallback) {
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService,
|
||||
Arrays.asList(DetailType.values()));
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> defaultSettings = autoplayLifecycle
|
||||
.createDefaultSettings();
|
||||
settingsCallback.newSettings(defaultSettings,
|
||||
getUrlWithSettings(apcd, defaultSettings, leaderboard, userService));
|
||||
}
|
||||
|
||||
private String getUrlWithSettings(AutoPlayContextDefinition apcd,
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> settings, StrippedLeaderboardDTO leaderboard,
|
||||
UserService userService) {
|
||||
AutoplayPerspectiveLifecycle autoplayLifecycle = new AutoplayPerspectiveLifecycle(leaderboard, userService,
|
||||
Arrays.asList(DetailType.values()));
|
||||
LinkWithSettingsGenerator<PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings>> settingsGenerator = new LinkWithSettingsGenerator<>(
|
||||
Window.Location.getPath(), autoplayLifecycle::createDefaultSettings, apcd);
|
||||
|
||||
return settingsGenerator.createUrl(settings);
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -93,11 +93,11 @@ public class IdleSixtyInchLeaderboardNode extends FiresPlaceNode {
|
||||
|
||||
private void startWithLeaderbaord(final MultiRaceLeaderboardSettings leaderboardSettings,
|
||||
CompetitorSelectionProvider provider, String leaderboardName) {
|
||||
MultiRaceLeaderboardPanel leaderboardPanel = new MultiRaceLeaderboardPanel(null, null, cf.getSailingService(),
|
||||
new AsyncActionsExecutor(), leaderboardSettings, false, provider, timer, null, leaderboardName,
|
||||
cf.getErrorReporter(), StringMessages.INSTANCE, false, null, false, null, false, true, false, false,
|
||||
false, new SixtyInchLeaderboardStyle(true), FlagImageResolverImpl.get(),
|
||||
Arrays.asList(DetailType.values()));
|
||||
MultiRaceLeaderboardPanel leaderboardPanel = new MultiRaceLeaderboardPanel(null, null,
|
||||
cf.getSailingService(() -> leaderboardName), new AsyncActionsExecutor(), leaderboardSettings, false,
|
||||
provider, timer, null, leaderboardName, cf.getErrorReporter(), StringMessages.INSTANCE, false, null,
|
||||
false, null, false, true, false, false, false, new SixtyInchLeaderboardStyle(true),
|
||||
FlagImageResolverImpl.get(), Arrays.asList(DetailType.values()));
|
||||
|
||||
IdleSixtyInchLeaderboardPlace place = new IdleSixtyInchLeaderboardPlace(leaderboardPanel, provider,
|
||||
durationConsumer);
|
||||
|
||||
+2
-2
@@ -55,10 +55,10 @@ public class AutoPlayStartPresenterImpl extends AbstractActivity implements Auto
|
||||
StrippedLeaderboardDTO leaderBoard = AutoplayHelper.getSelectedLeaderboard(event,
|
||||
apcd.getLeaderboardName());
|
||||
|
||||
apcd.getType().getConfig().loadSettingsDefault(event, leaderBoard, clientFactory.getUserService(), new OnSettingsCallback() {
|
||||
apcd.getType().getConfig().loadSettingsDefault(event, apcd, leaderBoard, clientFactory.getUserService(), new OnSettingsCallback() {
|
||||
|
||||
@Override
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings) {
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings) {
|
||||
if (newSettings != null) {
|
||||
serializer.deserializeSettingsMapFromCurrentLocation(newSettings);
|
||||
}
|
||||
|
||||
+9
-18
@@ -8,7 +8,6 @@ import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Style.Display;
|
||||
import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.http.client.UrlBuilder;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
@@ -30,8 +29,6 @@ import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.GWTLocaleUtil;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.gwt.settings.UrlBuilderUtil;
|
||||
|
||||
public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartView {
|
||||
private static StartPageViewUiBinder uiBinder = GWT.create(StartPageViewUiBinder.class);
|
||||
@@ -151,9 +148,9 @@ public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartVie
|
||||
selectedAutoPlayType.getConfig().openSettingsDialog(selectedEvent, selectedLeaderboard,
|
||||
new OnSettingsCallback() {
|
||||
@Override
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings) {
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings) {
|
||||
settings = newSettings;
|
||||
updateURL();
|
||||
updateURL(urlWithSettings);
|
||||
}
|
||||
}, settings, apcd, currentPresenter.getUserService());
|
||||
}
|
||||
@@ -197,12 +194,12 @@ public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartVie
|
||||
settingsButton.removeStyleName(SharedResources.INSTANCE.mainCss().buttoninactive());
|
||||
startAutoPlayButton.removeStyleName(SharedResources.INSTANCE.mainCss().buttoninactive());
|
||||
apcd = new AutoPlayContextDefinitionImpl(selectedAutoPlayType, selectedEvent.id, selectedLeaderboardName);
|
||||
apcd.getType().getConfig().loadSettingsDefault(selectedEvent, selectedLeaderboard, currentPresenter.getUserService(),
|
||||
apcd.getType().getConfig().loadSettingsDefault(selectedEvent, apcd, selectedLeaderboard, currentPresenter.getUserService(),
|
||||
new OnSettingsCallback() {
|
||||
@Override
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings) {
|
||||
public void newSettings(PerspectiveCompositeSettings<?> newSettings, String urlWithSettings) {
|
||||
settings = newSettings;
|
||||
updateURL();
|
||||
updateURL(urlWithSettings);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -210,16 +207,10 @@ public class AutoPlayStartViewImpl extends Composite implements AutoPlayStartVie
|
||||
return readyToGo;
|
||||
}
|
||||
|
||||
private void updateURL() {
|
||||
UrlBuilder urlBuilder = UrlBuilderUtil.createUrlBuilderFromCurrentLocationWithCleanParameters();
|
||||
SettingsToUrlSerializer urlSerializer = new SettingsToUrlSerializer();
|
||||
if (settings != null) {
|
||||
urlSerializer.serializeSettingsMapToUrlBuilder(settings, urlBuilder);
|
||||
}
|
||||
urlSerializer.serializeToUrlBuilder(apcd, urlBuilder);
|
||||
configuratedUrl = urlBuilder.buildString();
|
||||
configStarter.setText(configuratedUrl);
|
||||
configStarter.setHref(configuratedUrl);
|
||||
private void updateURL(String urlWithSettings) {
|
||||
configuratedUrl = urlWithSettings;
|
||||
configStarter.setText(urlWithSettings);
|
||||
configStarter.setHref(urlWithSettings);
|
||||
}
|
||||
|
||||
@UiHandler("localeSelectionBox")
|
||||
|
||||
+2
@@ -6,6 +6,8 @@
|
||||
<inherits name="com.sap.sse.gwt.CommonSharedResources" />
|
||||
|
||||
<source path='client'/>
|
||||
<source path='communication'/>
|
||||
<source path='theme'/>
|
||||
|
||||
</module>
|
||||
|
||||
+1
@@ -59,6 +59,7 @@ public class BoatClassImageResolver {
|
||||
boatClassIconsMap.put(BoatClassMasterdata.FARR_280.getDisplayName(), imageResources.Farr280Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.FINN.getDisplayName(), imageResources.FinnIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.FLYING_DUTCHMAN.getDisplayName(), imageResources.FlyingDutchmanIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.FLYING_JUNIOR.getDisplayName(), imageResources.FlyingJuniorIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.FOLKBOAT.getDisplayName(), imageResources.FolkBoatIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.FUN.getDisplayName(), imageResources.FUNIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.GC_32.getDisplayName(), imageResources.GC32Icon());
|
||||
|
||||
+4
@@ -132,6 +132,10 @@ public interface BoatClassImageResources extends ClientBundle {
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource FinnIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/FLYING_JUNIOR.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource FlyingJuniorIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/FLYING_DUTCHMAN.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource FlyingDutchmanIcon();
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.gwt.common.communication.routing;
|
||||
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sse.gwt.client.ServiceRoutingProvider;
|
||||
|
||||
/**
|
||||
* Interface used to provide leaderboard specific routing, see {@link ServiceRoutingProvider}
|
||||
*/
|
||||
public interface ProvidesLeaderboardRouting extends ServiceRoutingProvider {
|
||||
|
||||
String getLeaderboardName();
|
||||
|
||||
default String routingSuffixPath() {
|
||||
return ShardingType.LEADERBOARDNAME.encodeIfNeeded(getLeaderboardName());
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.home.communication.event;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
@@ -26,7 +27,7 @@ import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
|
||||
* </p>
|
||||
*/
|
||||
public class GetCompetitionFormatRacesAction implements
|
||||
SailingAction<ResultWithTTL<ListResult<RaceCompetitionFormatSeriesDTO>>>, IsClientCacheable {
|
||||
SailingAction<ResultWithTTL<ListResult<RaceCompetitionFormatSeriesDTO>>>, IsClientCacheable, ProvidesLeaderboardRouting {
|
||||
|
||||
private UUID eventId;
|
||||
private String regattaId;
|
||||
@@ -58,4 +59,9 @@ public class GetCompetitionFormatRacesAction implements
|
||||
public void cacheInstanceKey(StringBuilder key) {
|
||||
key.append(eventId).append("_").append(regattaId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaId;
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.home.communication.event;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
@@ -25,7 +26,7 @@ import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
* </p>
|
||||
*/
|
||||
public class GetFinishedRacesAction implements SailingAction<ResultWithTTL<ListResult<RaceListRaceDTO>>>,
|
||||
IsClientCacheable {
|
||||
IsClientCacheable, ProvidesLeaderboardRouting {
|
||||
|
||||
private UUID eventId;
|
||||
private String regattaId;
|
||||
@@ -59,4 +60,9 @@ public class GetFinishedRacesAction implements SailingAction<ResultWithTTL<ListR
|
||||
public void cacheInstanceKey(StringBuilder key) {
|
||||
key.append(eventId).append("_").append(regattaId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaId;
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -4,6 +4,7 @@ import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
@@ -30,7 +31,7 @@ import com.sap.sse.gwt.dispatch.shared.commands.SortedSetResult;
|
||||
* </p>
|
||||
*/
|
||||
public class GetLiveRacesForRegattaAction implements SailingAction<ResultWithTTL<SortedSetResult<LiveRaceDTO>>>,
|
||||
IsClientCacheable {
|
||||
IsClientCacheable, ProvidesLeaderboardRouting {
|
||||
private UUID eventId;
|
||||
private String regattaName;
|
||||
|
||||
@@ -66,4 +67,10 @@ public class GetLiveRacesForRegattaAction implements SailingAction<ResultWithTTL
|
||||
public void cacheInstanceKey(StringBuilder key) {
|
||||
key.append(eventId).append("_").append(regattaName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaName;
|
||||
}
|
||||
|
||||
}
|
||||
+7
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.home.communication.event;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.communication.event.statistics.EventStatisticsDTO;
|
||||
@@ -22,7 +23,7 @@ import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
|
||||
* The {@link ResultWithTTL result's} time to live is <i>5 minutes</i>.
|
||||
* </p>
|
||||
*/
|
||||
public class GetRegattaStatisticsAction implements SailingAction<ResultWithTTL<EventStatisticsDTO>>, IsClientCacheable {
|
||||
public class GetRegattaStatisticsAction implements SailingAction<ResultWithTTL<EventStatisticsDTO>>, IsClientCacheable, ProvidesLeaderboardRouting {
|
||||
|
||||
private UUID eventId;
|
||||
private String regattaId;
|
||||
@@ -53,4 +54,9 @@ public class GetRegattaStatisticsAction implements SailingAction<ResultWithTTL<E
|
||||
public void cacheInstanceKey(StringBuilder key) {
|
||||
key.append(eventId).append("_").append(regattaId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaId;
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.home.communication.event;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.communication.regatta.RegattaWithProgressDTO;
|
||||
@@ -24,7 +25,7 @@ import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
* state} using a duration of <i>5 minutes</i> for currently running events.
|
||||
* </p>
|
||||
*/
|
||||
public class GetRegattaWithProgressAction implements SailingAction<ResultWithTTL<RegattaWithProgressDTO>>, IsClientCacheable {
|
||||
public class GetRegattaWithProgressAction implements SailingAction<ResultWithTTL<RegattaWithProgressDTO>>, IsClientCacheable, ProvidesLeaderboardRouting {
|
||||
|
||||
private UUID eventId;
|
||||
private String regattaId;
|
||||
@@ -55,4 +56,9 @@ public class GetRegattaWithProgressAction implements SailingAction<ResultWithTTL
|
||||
public void cacheInstanceKey(StringBuilder key) {
|
||||
key.append(eventId).append("_").append(regattaId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaId;
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -4,6 +4,7 @@ import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil;
|
||||
@@ -21,7 +22,7 @@ import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
* otherwise.
|
||||
* </p>
|
||||
*/
|
||||
public class GetMiniLeaderbordAction implements SailingAction<ResultWithTTL<GetMiniLeaderboardDTO>>, IsClientCacheable {
|
||||
public class GetMiniLeaderbordAction implements SailingAction<ResultWithTTL<GetMiniLeaderboardDTO>>, IsClientCacheable, ProvidesLeaderboardRouting {
|
||||
private UUID eventId;
|
||||
private String leaderboardName;
|
||||
private int limit = 0;
|
||||
@@ -74,4 +75,9 @@ public class GetMiniLeaderbordAction implements SailingAction<ResultWithTTL<GetM
|
||||
key.append("_");
|
||||
key.append(limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderboardName;
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.TargetTimeInfo;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.communication.SailingAction;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sse.common.Distance;
|
||||
@@ -32,7 +33,7 @@ import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
* otherwise.
|
||||
* </p>
|
||||
*/
|
||||
public class GetSixtyInchStatisticAction implements SailingAction<GetSixtyInchStatisticDTO> {
|
||||
public class GetSixtyInchStatisticAction implements SailingAction<GetSixtyInchStatisticDTO>, ProvidesLeaderboardRouting {
|
||||
private static final Logger LOGGER = Logger.getLogger(GetSixtyInchStatisticAction.class.getName());
|
||||
// transfer as string, to avoid transfering incompatible types
|
||||
private String racename;
|
||||
@@ -95,4 +96,9 @@ public class GetSixtyInchStatisticAction implements SailingAction<GetSixtyInchSt
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaname;
|
||||
}
|
||||
}
|
||||
+12
-3
@@ -5,12 +5,13 @@ import com.google.gwt.place.shared.Place;
|
||||
import com.google.gwt.place.shared.PlaceController;
|
||||
import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.google.web.bindery.event.shared.EventBus;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.home.shared.places.start.StartPlace;
|
||||
import com.sap.sailing.gwt.ui.client.MediaService;
|
||||
import com.sap.sailing.gwt.ui.client.MediaServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.RemoteServiceMappingConstants;
|
||||
import com.sap.sailing.gwt.ui.client.SailingService;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceHelper;
|
||||
import com.sap.sse.gwt.client.EntryPointHelper;
|
||||
import com.sap.sse.security.ui.client.SecureClientFactoryImpl;
|
||||
|
||||
@@ -24,9 +25,8 @@ public abstract class AbstractApplicationClientFactory<ATLV extends ApplicationT
|
||||
PlaceController placeController, final DesktopPlacesNavigator navigator) {
|
||||
super(root, eventBus, placeController);
|
||||
this.navigator = navigator;
|
||||
sailingService = GWT.create(SailingService.class);
|
||||
sailingService = SailingServiceHelper.createSailingServiceInstance();
|
||||
mediaService = GWT.create(MediaService.class);
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) sailingService, RemoteServiceMappingConstants.sailingServiceRemotePath);
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) mediaService, RemoteServiceMappingConstants.mediaServiceRemotePath);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,15 @@ public abstract class AbstractApplicationClientFactory<ATLV extends ApplicationT
|
||||
return sailingService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SailingServiceAsync getSailingService(ProvidesLeaderboardRouting routingProvider) {
|
||||
if (routingProvider == null) {
|
||||
return sailingService;
|
||||
} else {
|
||||
return SailingServiceHelper.createSailingServiceInstance(routingProvider);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaServiceAsync getMediaService() {
|
||||
return mediaService;
|
||||
|
||||
+4
@@ -20,6 +20,7 @@ import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
import com.sap.sailing.gwt.home.shared.resources.SharedHomeResources;
|
||||
import com.sap.sailing.gwt.home.shared.utils.EventDatesFormatterUtil;
|
||||
import com.sap.sailing.gwt.home.shared.utils.LabelTypeUtil;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.LinkUtil;
|
||||
|
||||
public class EventTeaser extends Composite {
|
||||
@@ -85,6 +86,9 @@ public class EventTeaser extends Composite {
|
||||
|
||||
public void setSeriesInformation(PlaceNavigation<?> seriesNavigation, EventListEventSeriesDTO eventSeries) {
|
||||
eventImage.appendChild(new EventTeaserSeriesInfoCorner(seriesNavigation, eventSeries).getElement());
|
||||
eventName.setInnerSafeHtml(LongNamesUtil.breakLongName(eventSeries.getDisplayName()));
|
||||
venue.setInnerText(StringMessages.INSTANCE.lastEvent(event.getLocationOrVenue()));
|
||||
eventImage.setTitle(StringMessages.INSTANCE.teaserOverallLinkToolTip());
|
||||
}
|
||||
|
||||
public void hideImage(boolean hide) {
|
||||
|
||||
-5
@@ -37,7 +37,6 @@ import com.sap.sailing.gwt.settings.client.raceboard.RaceBoardPerspectiveOwnSett
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaOverviewContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.regattaoverview.RegattaRaceStatesSettings;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.refresh.ErrorAndBusyClientFactory;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapLifecycle;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapSettings;
|
||||
@@ -83,10 +82,6 @@ public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> ex
|
||||
this.timerForClientServerOffset = new Timer(PlayModes.Replay);
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
public SailingServiceAsync getSailingService() {
|
||||
return clientFactory.getSailingService();
|
||||
}
|
||||
|
||||
public SailingDispatchSystem getDispatch() {
|
||||
return clientFactory.getDispatch();
|
||||
|
||||
-2
@@ -21,7 +21,6 @@ import com.sap.sailing.gwt.home.shared.places.event.EventDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.events.EventsPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.fakeseries.SeriesDefaultPlace;
|
||||
import com.sap.sailing.gwt.home.shared.places.start.StartPlace;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.refresh.ErrorAndBusyClientFactory;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
|
||||
@@ -37,7 +36,6 @@ public interface EventView<PLACE extends AbstractEventPlace, PRES extends EventV
|
||||
boolean needsSelectionInHeader();
|
||||
void forPlaceSelection(PlaceCallback callback);
|
||||
Timer getTimerForClientServerOffset();
|
||||
SailingServiceAsync getSailingService();
|
||||
|
||||
AbstractEventRegattaPlace getPlaceForRegatta(String regattaId);
|
||||
AbstractEventRegattaPlace getPlaceForRegattaRaces(String regattaId);
|
||||
|
||||
+10
-1
@@ -4,7 +4,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.event.shared.EventBus;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.AcceptsOneWidget;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.EventType;
|
||||
import com.sap.sailing.gwt.home.communication.event.EventReferenceWithStateDTO;
|
||||
import com.sap.sailing.gwt.home.communication.event.EventState;
|
||||
@@ -50,7 +53,7 @@ public class EventRegattaActivity extends AbstractEventActivity<AbstractEventReg
|
||||
currentView = new TabletAndDesktopRegattaEventView(flagImageResolver);
|
||||
if (this.ctx.getRegattaAnalyticsManager() == null) {
|
||||
ctx.withRegattaAnalyticsManager(new RegattaAnalyticsDataManager(
|
||||
clientFactory.getSailingService(),
|
||||
clientFactory,
|
||||
asyncActionsExecutor,
|
||||
new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds),
|
||||
clientFactory.getErrorReporter(), flagImageResolver));
|
||||
@@ -158,4 +161,10 @@ public class EventRegattaActivity extends AbstractEventActivity<AbstractEventReg
|
||||
public UserService getUserService() {
|
||||
return clientFactory.getUserService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAvailableDetailTypesForLeaderboard(String leaderboardName, RegattaAndRaceIdentifier raceOrNull,
|
||||
AsyncCallback<Iterable<DetailType>> asyncCallback) {
|
||||
clientFactory.getSailingService(()-> leaderboardName).getAvailableDetailTypesForLeaderboard(leaderboardName, raceOrNull, asyncCallback);
|
||||
}
|
||||
}
|
||||
+6
@@ -1,5 +1,8 @@
|
||||
package com.sap.sailing.gwt.home.desktop.places.event.regatta;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.EventView;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.regatta.overviewtab.RegattaOverviewPlace;
|
||||
import com.sap.sailing.gwt.home.shared.app.PlaceNavigation;
|
||||
@@ -15,5 +18,8 @@ public interface EventRegattaView extends EventView<AbstractEventRegattaPlace, E
|
||||
Timer getAutoRefreshTimer();
|
||||
|
||||
UserService getUserService();
|
||||
|
||||
void getAvailableDetailTypesForLeaderboard(String leaderboardName, RegattaAndRaceIdentifier raceOrNull,
|
||||
AsyncCallback<Iterable<DetailType>> asyncCallback);
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -6,6 +6,7 @@ import com.sap.sailing.gwt.settings.client.leaderboard.MultiRaceLeaderboardSetti
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
|
||||
import com.sap.sailing.gwt.ui.client.FlagImageResolver;
|
||||
import com.sap.sailing.gwt.ui.client.SailingClientFactory;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
|
||||
@@ -31,16 +32,16 @@ public class RegattaAnalyticsDataManager {
|
||||
private final CompetitorSelectionModel competitorSelectionProvider;
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final SailingClientFactory sailingCF;
|
||||
private final Timer timer;
|
||||
private final FlagImageResolver flagImageResolver;
|
||||
|
||||
public RegattaAnalyticsDataManager(final SailingServiceAsync sailingService,
|
||||
public RegattaAnalyticsDataManager(final SailingClientFactory sailingCF,
|
||||
AsyncActionsExecutor asyncActionsExecutor, Timer timer, ErrorReporter errorReporter,
|
||||
FlagImageResolver flagImageResolver) {
|
||||
this.flagImageResolver = flagImageResolver;
|
||||
this.competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true);
|
||||
this.sailingService = sailingService;
|
||||
this.sailingCF = sailingCF;
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
this.timer = timer;
|
||||
this.errorReporter = errorReporter;
|
||||
@@ -53,6 +54,7 @@ public class RegattaAnalyticsDataManager {
|
||||
final String leaderboardGroupName, String leaderboardName, boolean showRaceDetails,
|
||||
boolean autoExpandLastRaceColumn, Iterable<DetailType> availableDetailTypes) {
|
||||
if (leaderboardPanel == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
leaderboardPanel = new MultiRaceLeaderboardPanel(parent, context, sailingService,
|
||||
asyncActionsExecutor,
|
||||
leaderboardSettings,
|
||||
@@ -68,6 +70,7 @@ public class RegattaAnalyticsDataManager {
|
||||
|
||||
public MultiCompetitorLeaderboardChart createMultiCompetitorChart(String leaderboardName, DetailType chartDetailType) {
|
||||
if(multiCompetitorChart == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
multiCompetitorChart = new MultiCompetitorLeaderboardChart(null, null, sailingService, asyncActionsExecutor,
|
||||
leaderboardName, chartDetailType,
|
||||
competitorSelectionProvider, timer, StringMessages.INSTANCE, false, errorReporter);
|
||||
|
||||
+2
-2
@@ -99,8 +99,8 @@ public class RegattaCompetitorAnalyticsTabView extends SharedLeaderboardRegattaT
|
||||
}
|
||||
};
|
||||
if (regattaAnalyticsManager.getLeaderboardPanel() == null) {
|
||||
currentPresenter.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
currentPresenter.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
|
||||
+2
-2
@@ -147,8 +147,8 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
|
||||
|
||||
private void loadAvailableDetailTypes(final String leaderboardName, final AcceptsOneWidget contentArea,
|
||||
final Consumer<Iterable<DetailType>> callback) {
|
||||
currentPresenter.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
currentPresenter.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
|
||||
+19
-7
@@ -4,7 +4,9 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.MultiCompetitorLeaderboardChartSettings;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.MultiRaceLeaderboardSettings;
|
||||
@@ -12,6 +14,7 @@ import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
|
||||
import com.sap.sailing.gwt.ui.client.FlagImageResolver;
|
||||
import com.sap.sailing.gwt.ui.client.SailingClientFactory;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
|
||||
@@ -42,33 +45,32 @@ public class EventSeriesAnalyticsDataManager {
|
||||
private final CompetitorSelectionModel competitorSelectionProvider;
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final SailingClientFactory sailingCF;
|
||||
private final Timer timer;
|
||||
private final int MAX_COMPETITORS_IN_CHART = 30;
|
||||
private final FlagImageResolver flagImageResolver;
|
||||
|
||||
public EventSeriesAnalyticsDataManager(final SailingServiceAsync sailingService,
|
||||
public EventSeriesAnalyticsDataManager(final SailingClientFactory sailingCF,
|
||||
AsyncActionsExecutor asyncActionsExecutor, Timer timer, ErrorReporter errorReporter,
|
||||
FlagImageResolver flagImageResolver) {
|
||||
this.flagImageResolver = flagImageResolver;
|
||||
this.competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true);
|
||||
this.sailingService = sailingService;
|
||||
this.sailingCF = sailingCF;
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
this.timer = timer;
|
||||
this.errorReporter = errorReporter;
|
||||
this.overallLeaderboardPanel = null;
|
||||
this.multiCompetitorChart = null;
|
||||
}
|
||||
|
||||
public SailingServiceAsync getSailingService() {
|
||||
return sailingService;
|
||||
}
|
||||
|
||||
public MultiRaceLeaderboardPanel createMultiRaceOverallLeaderboardPanel(Component<?> parent, ComponentContext<?> context,
|
||||
final MultiRaceLeaderboardSettings leaderboardSettings,
|
||||
final String leaderboardGroupName, String leaderboardName, boolean showRaceDetails,
|
||||
boolean autoExpandLastRaceColumn, Iterable<DetailType> availableDetailTypes) {
|
||||
|
||||
|
||||
if(overallLeaderboardPanel == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
overallLeaderboardPanel = new MultiRaceLeaderboardPanel(parent, context, sailingService, asyncActionsExecutor,
|
||||
leaderboardSettings, true,
|
||||
competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter,
|
||||
@@ -84,7 +86,10 @@ public class EventSeriesAnalyticsDataManager {
|
||||
public MultiCompetitorLeaderboardChart createMultiCompetitorChart(Component<?> parent,
|
||||
ComponentContext<?> context, String leaderboardName,
|
||||
DetailType chartDetailType) {
|
||||
|
||||
if(multiCompetitorChart == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
|
||||
multiCompetitorChart = new MultiCompetitorLeaderboardChart(parent, context, sailingService,
|
||||
asyncActionsExecutor,
|
||||
leaderboardName, chartDetailType,
|
||||
@@ -99,6 +104,7 @@ public class EventSeriesAnalyticsDataManager {
|
||||
String preselectedLeaderboardName, String leaderboardGroupName,
|
||||
String metaLeaderboardName, boolean showRaceDetails, boolean autoExpandLastRaceColumn, Iterable<DetailType> availableDetailTypes) {
|
||||
if(multiLeaderboardPanel == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> metaLeaderboardName);
|
||||
multiLeaderboardPanel = new MultiLeaderboardProxyPanel(parent, context, sailingService, metaLeaderboardName,
|
||||
asyncActionsExecutor, timer, true /* isEmbedded */,
|
||||
preselectedLeaderboardName, errorReporter, StringMessages.INSTANCE,
|
||||
@@ -179,4 +185,10 @@ public class EventSeriesAnalyticsDataManager {
|
||||
public Timer getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
public void getAvailableDetailTypesForLeaderboard(String leaderboardName, RegattaAndRaceIdentifier raceOrNull,
|
||||
AsyncCallback<Iterable<DetailType>> asyncCallback) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName, raceOrNull, asyncCallback);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class SeriesActivity extends AbstractActivity implements SeriesView.Prese
|
||||
|
||||
if (this.ctx.getAnalyticsManager() == null) {
|
||||
ctx.withAnalyticsManager(new EventSeriesAnalyticsDataManager( //
|
||||
clientFactory.getSailingService(), //
|
||||
clientFactory, //
|
||||
asyncActionsExecutor, //
|
||||
new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds), //
|
||||
clientFactory.getErrorReporter(), flagImageResolver));
|
||||
|
||||
+2
-2
@@ -78,8 +78,8 @@ public class EventSeriesCompetitorAnalyticsTabView extends SharedLeaderboardEven
|
||||
}
|
||||
};
|
||||
if (eventSeriesAnalyticsManager.getLeaderboardPanel() == null) {
|
||||
eventSeriesAnalyticsManager.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
eventSeriesAnalyticsManager.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
|
||||
+2
-2
@@ -77,8 +77,8 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT
|
||||
final EventSeriesAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx()
|
||||
.getAnalyticsManager();
|
||||
|
||||
regattaAnalyticsManager.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
regattaAnalyticsManager.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ public class EventSeriesOverallLeaderboardTabView extends SharedLeaderboardEvent
|
||||
contentArea.setWidget(currentPresenter.getErrorAndBusyClientFactory().createBusyView());
|
||||
String leaderboardName = currentPresenter.getSeriesDTO().getLeaderboardId();
|
||||
if (leaderboardName != null && !leaderboardName.isEmpty()) {
|
||||
currentPresenter.getCtx().getAnalyticsManager().getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName, new AsyncCallback<Iterable<DetailType>>() {
|
||||
currentPresenter.getCtx().getAnalyticsManager().getAvailableDetailTypesForLeaderboard(leaderboardName, null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
|
||||
+13
-6
@@ -4,6 +4,14 @@
|
||||
<div id="mainContent">
|
||||
<h4 class="articleHeadline">What's New - SAP Sailing Race Manager</h4>
|
||||
<div class="innerContent">
|
||||
<h5 class="articleSubheadline">February 2018</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The protest time is now configurable in the backend. An empty value means, the RCApp
|
||||
will take 90 minutes as default. If no time is set in the backend, the RCApp will save a
|
||||
custom duration as new default. A server side duration (device or regatta specific) will always
|
||||
be the default.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">August 2017</h5>
|
||||
<ul class="bulletList">
|
||||
<li>The result list can now be edited without a finish time.</li>
|
||||
@@ -22,6 +30,11 @@
|
||||
for the competitor is cleared, the rank is set to 0 and the penalty is
|
||||
set to "NONE" then the competitor will remain in the list, and this
|
||||
"empty" result will be sent to the server, clearing any previous score
|
||||
corrections that were sent to the server. This is the only way to
|
||||
"reset" an erroneous score correction entirely from the app, because
|
||||
swiping and thus removing the competitor from the list would leave the
|
||||
previous score correction unchanged on the server upon the next result
|
||||
publication.
|
||||
</li>
|
||||
<li>When entering and publishing partial results, updates will only be applied
|
||||
for those competitors for which a result has been entered. In particular,
|
||||
@@ -30,12 +43,6 @@
|
||||
partial results entered on one device will not unnecessarily remove changes
|
||||
applied on another device.
|
||||
</li>
|
||||
corrections that were sent to the server. This is the only way to
|
||||
"reset" an erroneous score correction entirely from the app, because
|
||||
swiping and thus removing the competitor from the list would leave the
|
||||
previous score correction unchanged on the server upon the next result
|
||||
publication.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2017</h5>
|
||||
|
||||
+24
@@ -1,8 +1,17 @@
|
||||
package com.sap.sailing.gwt.home.server.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.sharding.ShardingContext;
|
||||
import com.sap.sailing.domain.windfinder.WindFinderTrackerFactory;
|
||||
import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
|
||||
import com.sap.sailing.gwt.home.server.SailingDispatchContextImpl;
|
||||
@@ -47,4 +56,19 @@ public class SailingDispatchServlet extends AbstractDispatchServlet<SailingDispa
|
||||
userStoreTracker.getService(), trackedRaceStatisticsCacheTracker.getService(),
|
||||
request.getClientLocaleName(), getThreadLocalRequest());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
||||
ShardingType identifiedShardingType = null;
|
||||
try {
|
||||
if (req instanceof HttpServletRequest) {
|
||||
identifiedShardingType = ShardingContext.identifyAndSetShardingConstraint( ((HttpServletRequest) req).getPathInfo());
|
||||
}
|
||||
super.service(req, res);
|
||||
} finally {
|
||||
if (identifiedShardingType != null) {
|
||||
ShardingContext.clearShardingConstraint(identifiedShardingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-2
@@ -26,8 +26,6 @@ public interface AnniversaryLegalMessages extends Messages{
|
||||
String anniversaryLegalNoticeSectionContestParagraph(int anniversary);
|
||||
String anniversaryLegalNoticeSectionCommunicationParagraphTitle();
|
||||
String anniversaryLegalNoticeSectionCommunicationParagraph();
|
||||
String anniversaryLegalNoticeSectionCharitablyPurposeParagraphTitle();
|
||||
String anniversaryLegalNoticeSectionCharitablyPurposeParagraph();
|
||||
String anniversaryLegalNoticeSectionPrizesParagraphTitle();
|
||||
String anniversaryLegalNoticeSectionPrizesParagraph(int anniversary);
|
||||
String anniversaryLegalNoticeSectionPersonalDataAndRightsToImagesParagraphTitle();
|
||||
|
||||
+2
-4
@@ -7,18 +7,16 @@ anniversaryLegalNoticeSectionOrganizationAndParticipationParagraph3=The organize
|
||||
anniversaryLegalNoticeSectionRequirementsHeadline=Prerequisites
|
||||
anniversaryLegalNoticeSectionRequirementsListItem1=SAP Sailing Analytics must be responsible for the live data analysis of each race.
|
||||
anniversaryLegalNoticeSectionRequirementsListItem2=To win the prize, a race must enter into the regatta evaluation and be finished.
|
||||
anniversaryLegalNoticeSectionRequirementsListItem3=The \u20AC10,000 are to be used solely for charitable purposes.
|
||||
anniversaryLegalNoticeSectionRequirementsListItem3=The prize money is used solely for the purpose of paying catering (food, beverage, service).
|
||||
anniversaryLegalNoticeSectionContestParagraphTitle=Contest
|
||||
anniversaryLegalNoticeSectionContestParagraph=The contest will run until the {0,number,#,###}th race has begun.
|
||||
anniversaryLegalNoticeSectionCommunicationParagraphTitle=Notification
|
||||
anniversaryLegalNoticeSectionCommunicationParagraph=The winner will be automatically announced at www.sapsailing.com.
|
||||
anniversaryLegalNoticeSectionCharitablyPurposeParagraphTitle=Charitable purposes
|
||||
anniversaryLegalNoticeSectionCharitablyPurposeParagraph=The charitable purpose for which the prize is to be used must fulfill certain requirements. The winner must invest the prize in promoting sports, education, literature, the public good, health and safety, the fight against poverty, or similar aims without attempting to gain any private benefit, profit, or political influence.
|
||||
anniversaryLegalNoticeSectionPrizesParagraphTitle=Prizes
|
||||
anniversaryLegalNoticeSectionPrizesParagraph=The organizer of the {0,number,#,###}th race will receive the prize money.
|
||||
anniversaryLegalNoticeSectionPersonalDataAndRightsToImagesParagraphTitle=Personal data and image rights
|
||||
anniversaryLegalNoticeSectionPersonalDataAndRightsToImagesParagraph1=By participating in the contest, each organizer grants permission (and warrants to have received corresponding consent from its members) to the organizer, its subsidiaries and affiliated businesses, respective licensees, successors, and assignees to use the contest winner''s name, likeness, and entry for purposes of advertising and trade without further notice, consent, or compensation with regard to the contest and the event at which the contest took place, unless prohibited by law. This includes printing, publishing, broadcasting, distributing, and using the contest winner''s name, portrait, picture, voice, likeness, or image (or statements from associated members about the contest) for promotional purposes in any media now known or hereafter arising anywhere in the world.
|
||||
anniversaryLegalNoticeSectionPersonalDataAndRightsToImagesParagraph2=SAP SE has set the total sum at \u20AC10,000. Event organizers must propose a charitable purpose for which they plan to use the prize to SAP SE. SAP SE reserves the right to approve these proposals or reject them should they not be deemed charitable.
|
||||
anniversaryLegalNoticeSectionPersonalDataAndRightsToImagesParagraph2=SAP SE has set the total sum at \u20AC3,000. Event organizers must propose a catering plan to SAP SE. SAP SE reserves the right to approve the proposal or reject it.
|
||||
anniversaryLegalNoticeSectionDisclaimerSectionParagraphTitle=Disclaimer
|
||||
anniversaryLegalNoticeSectionDisclaimerSectionParagraph=SAP will assume no responsibility or liability for incomplete, inaccurate, or misdirected entries.
|
||||
anniversaryLegalNoticeSectionOtherParagraphTitle=Additional information
|
||||
|
||||
-4
@@ -41,10 +41,6 @@
|
||||
<span><ui:text from="{i18n.anniversaryLegalNoticeSectionCommunicationParagraphTitle}"/></span>
|
||||
<span><ui:text from="{i18n.anniversaryLegalNoticeSectionCommunicationParagraph}"/></span>
|
||||
</p>
|
||||
<p>
|
||||
<span><ui:text from="{i18n.anniversaryLegalNoticeSectionCharitablyPurposeParagraphTitle}"/></span>
|
||||
<span><ui:text from="{i18n.anniversaryLegalNoticeSectionCharitablyPurposeParagraph}"/></span>
|
||||
</p>
|
||||
<p>
|
||||
<span><ui:text from="{i18n.anniversaryLegalNoticeSectionPrizesParagraphTitle}"/></span>
|
||||
<span ui:field="legalNoticeSectionPrizes"></span>
|
||||
|
||||
+2
-1
@@ -64,6 +64,7 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
createAndAddDetailPanel();
|
||||
createAndAddRegattaPanel(regattaOverviewContextDefinition);
|
||||
toggleDetailPanel(false);
|
||||
@@ -88,7 +89,7 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
|
||||
private void createAndAddRegattaPanel(RegattaOverviewContextDefinition regattaOverviewContextDefinition) {
|
||||
regattaPanel = new RegattaOverviewPanel(sailingService, getUserService(), this, getStringMessages(),
|
||||
regattaPanel = new RegattaOverviewPanel(getSailingService(), getUserService(), this, getStringMessages(),
|
||||
regattaOverviewContextDefinition);
|
||||
|
||||
regattaPanel.addHandler(new EventDTOLoadedEvent.Handler() {
|
||||
|
||||
+28
-28
@@ -83,14 +83,14 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
|
||||
private Widget createAdminConsolePanel() {
|
||||
AdminConsolePanel panel = new AdminConsolePanel(getUserService(), SailingPermissionsForRoleProvider.INSTANCE,
|
||||
sailingService, getStringMessages().releaseNotes(), "/release_notes_admin.html", /* error reporter */ this, SecurityStylesheetResources.INSTANCE.css(), getStringMessages());
|
||||
getSailingService(), getStringMessages().releaseNotes(), "/release_notes_admin.html", /* error reporter */ this, SecurityStylesheetResources.INSTANCE.css(), getStringMessages());
|
||||
panel.addStyleName("adminConsolePanel");
|
||||
|
||||
regattasDisplayers = new HashSet<>();
|
||||
leaderboardsDisplayers = new HashSet<>();
|
||||
leaderboardGroupsDisplayers = new HashSet<>();
|
||||
|
||||
final EventManagementPanel eventManagementPanel = new EventManagementPanel(sailingService, this, this, getStringMessages(), panel);
|
||||
final EventManagementPanel eventManagementPanel = new EventManagementPanel(getSailingService(), this, this, getStringMessages(), panel);
|
||||
eventManagementPanel.ensureDebugId("EventManagement");
|
||||
panel.addToVerticalTabPanel(new DefaultRefreshableAdminConsolePanel<EventManagementPanel>(eventManagementPanel) {
|
||||
@Override
|
||||
@@ -104,7 +104,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
/* REGATTAS */
|
||||
|
||||
RegattaManagementPanel regattaManagementPanel = new RegattaManagementPanel(
|
||||
sailingService, this, getStringMessages(), this, eventManagementPanel);
|
||||
getSailingService(), this, getStringMessages(), this, eventManagementPanel);
|
||||
regattaManagementPanel.ensureDebugId("RegattaStructureManagement");
|
||||
panel.addToVerticalTabPanel(new DefaultRefreshableAdminConsolePanel<RegattaManagementPanel>(regattaManagementPanel) {
|
||||
@Override
|
||||
@@ -117,7 +117,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
/* LEADERBOARDS */
|
||||
|
||||
final HorizontalTabLayoutPanel leaderboardTabPanel = panel.addVerticalTab(getStringMessages().leaderboards(), "LeaderboardPanel");
|
||||
final LeaderboardConfigPanel leaderboardConfigPanel = new LeaderboardConfigPanel(sailingService, this, this,
|
||||
final LeaderboardConfigPanel leaderboardConfigPanel = new LeaderboardConfigPanel(getSailingService(), this, this,
|
||||
getStringMessages(), /* showRaceDetails */true, this);
|
||||
leaderboardConfigPanel.ensureDebugId("LeaderboardConfiguration");
|
||||
panel.addToTabPanel(leaderboardTabPanel, new DefaultRefreshableAdminConsolePanel<LeaderboardConfigPanel>(leaderboardConfigPanel) {
|
||||
@@ -129,7 +129,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
regattasDisplayers.add(leaderboardConfigPanel);
|
||||
leaderboardsDisplayers.add(leaderboardConfigPanel);
|
||||
|
||||
final LeaderboardGroupConfigPanel leaderboardGroupConfigPanel = new LeaderboardGroupConfigPanel(sailingService,
|
||||
final LeaderboardGroupConfigPanel leaderboardGroupConfigPanel = new LeaderboardGroupConfigPanel(getSailingService(),
|
||||
this, this, this, this, getStringMessages());
|
||||
leaderboardGroupConfigPanel.ensureDebugId("LeaderboardGroupConfiguration");
|
||||
panel.addToTabPanel(leaderboardTabPanel, new DefaultRefreshableAdminConsolePanel<LeaderboardGroupConfigPanel>(leaderboardGroupConfigPanel) {
|
||||
@@ -154,7 +154,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
final HorizontalTabLayoutPanel racesTabPanel = panel.addVerticalTab(getStringMessages().trackedRaces(), "RacesPanel");
|
||||
racesTabPanel.ensureDebugId("RacesPanel");
|
||||
|
||||
final TrackedRacesManagementPanel trackedRacesManagementPanel = new TrackedRacesManagementPanel(sailingService, this,
|
||||
final TrackedRacesManagementPanel trackedRacesManagementPanel = new TrackedRacesManagementPanel(getSailingService(), this,
|
||||
this, getStringMessages());
|
||||
trackedRacesManagementPanel.ensureDebugId("TrackedRacesManagement");
|
||||
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<TrackedRacesManagementPanel>(trackedRacesManagementPanel) {
|
||||
@@ -165,7 +165,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
}, getStringMessages().trackedRaces(), Permission.SHOW_TRACKED_RACES);
|
||||
regattasDisplayers.add(trackedRacesManagementPanel);
|
||||
|
||||
final CompetitorPanel competitorPanel = new CompetitorPanel(sailingService, getStringMessages(), this);
|
||||
final CompetitorPanel competitorPanel = new CompetitorPanel(getSailingService(), getStringMessages(), this);
|
||||
competitorPanel.ensureDebugId("CompetitorPanel");
|
||||
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<CompetitorPanel>(competitorPanel) {
|
||||
@Override
|
||||
@@ -174,7 +174,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
}
|
||||
}, getStringMessages().competitors(), Permission.MANAGE_ALL_COMPETITORS);
|
||||
|
||||
final BoatPanel boatPanel = new BoatPanel(sailingService, getStringMessages(), this);
|
||||
final BoatPanel boatPanel = new BoatPanel(getSailingService(), getStringMessages(), this);
|
||||
boatPanel.ensureDebugId("BoatPanel");
|
||||
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<BoatPanel>(boatPanel) {
|
||||
@Override
|
||||
@@ -183,18 +183,18 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
}
|
||||
}, getStringMessages().boats(), Permission.MANAGE_ALL_BOATS);
|
||||
|
||||
RaceCourseManagementPanel raceCourseManagementPanel = new RaceCourseManagementPanel(sailingService, this, this, getStringMessages());
|
||||
RaceCourseManagementPanel raceCourseManagementPanel = new RaceCourseManagementPanel(getSailingService(), this, this, getStringMessages());
|
||||
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<RaceCourseManagementPanel>(raceCourseManagementPanel), getStringMessages().courseLayout(), Permission.MANAGE_COURSE_LAYOUT);
|
||||
regattasDisplayers.add(raceCourseManagementPanel);
|
||||
|
||||
final AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
|
||||
WindPanel windPanel = new WindPanel(sailingService, asyncActionsExecutor, this, this, getStringMessages());
|
||||
WindPanel windPanel = new WindPanel(getSailingService(), asyncActionsExecutor, this, this, getStringMessages());
|
||||
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<WindPanel>(windPanel), getStringMessages().wind(),
|
||||
Permission.MANAGE_WIND);
|
||||
regattasDisplayers.add(windPanel);
|
||||
|
||||
final MediaPanel mediaPanel = new MediaPanel(regattasDisplayers, sailingService, this, mediaService, this, getStringMessages());
|
||||
final MediaPanel mediaPanel = new MediaPanel(regattasDisplayers, getSailingService(), this, mediaService, this, getStringMessages());
|
||||
panel.addToTabPanel(racesTabPanel, new DefaultRefreshableAdminConsolePanel<MediaPanel>(mediaPanel) {
|
||||
@Override
|
||||
public void refreshAfterBecomingVisible() {
|
||||
@@ -205,7 +205,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
/* RACE COMMITTEE APP */
|
||||
|
||||
final HorizontalTabLayoutPanel raceCommitteeTabPanel = panel.addVerticalTab(getStringMessages().raceCommitteeApp(), "RaceCommiteeAppPanel");
|
||||
final DeviceConfigurationUserPanel deviceConfigurationUserPanel = new DeviceConfigurationUserPanel(sailingService,
|
||||
final DeviceConfigurationUserPanel deviceConfigurationUserPanel = new DeviceConfigurationUserPanel(getSailingService(),
|
||||
getUserService(), getStringMessages(), this);
|
||||
panel.addToTabPanel(raceCommitteeTabPanel, new DefaultRefreshableAdminConsolePanel<DeviceConfigurationUserPanel>(deviceConfigurationUserPanel),
|
||||
getStringMessages().deviceConfiguration(), Permission.MANAGE_DEVICE_CONFIGURATION);
|
||||
@@ -213,7 +213,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
/* CONNECTORS */
|
||||
|
||||
final HorizontalTabLayoutPanel connectorsTabPanel = panel.addVerticalTab(getStringMessages().connectors(), "TrackingProviderPanel");
|
||||
TracTracEventManagementPanel tractracEventManagementPanel = new TracTracEventManagementPanel(sailingService,
|
||||
TracTracEventManagementPanel tractracEventManagementPanel = new TracTracEventManagementPanel(getSailingService(),
|
||||
this, this, getStringMessages());
|
||||
tractracEventManagementPanel.ensureDebugId("TracTracEventManagement");
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<TracTracEventManagementPanel>(tractracEventManagementPanel),
|
||||
@@ -221,19 +221,19 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
regattasDisplayers.add(tractracEventManagementPanel);
|
||||
|
||||
SwissTimingReplayConnectorPanel swissTimingReplayConnectorPanel = new SwissTimingReplayConnectorPanel(
|
||||
sailingService, this, this, getStringMessages());
|
||||
getSailingService(), this, this, getStringMessages());
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<SwissTimingReplayConnectorPanel>(swissTimingReplayConnectorPanel),
|
||||
getStringMessages().swissTimingArchiveConnector(), Permission.MANAGE_TRACKED_RACES);
|
||||
regattasDisplayers.add(swissTimingReplayConnectorPanel);
|
||||
|
||||
SwissTimingEventManagementPanel swisstimingEventManagementPanel = new SwissTimingEventManagementPanel(
|
||||
sailingService, this, this, getStringMessages());
|
||||
getSailingService(), this, this, getStringMessages());
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<SwissTimingEventManagementPanel>(swisstimingEventManagementPanel),
|
||||
getStringMessages().swissTimingEvents(), Permission.MANAGE_TRACKED_RACES);
|
||||
regattasDisplayers.add(swisstimingEventManagementPanel);
|
||||
|
||||
final SmartphoneTrackingEventManagementPanel raceLogTrackingEventManagementPanel = new SmartphoneTrackingEventManagementPanel(
|
||||
sailingService, this, this, this, getStringMessages());
|
||||
getSailingService(), this, this, this, getStringMessages());
|
||||
raceLogTrackingEventManagementPanel.ensureDebugId("SmartphoneTrackingPanel");
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<SmartphoneTrackingEventManagementPanel>(raceLogTrackingEventManagementPanel) {
|
||||
@Override
|
||||
@@ -244,12 +244,12 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
regattasDisplayers.add(raceLogTrackingEventManagementPanel);
|
||||
leaderboardsDisplayers.add(raceLogTrackingEventManagementPanel);
|
||||
|
||||
IgtimiAccountsPanel igtimiAccountsPanel = new IgtimiAccountsPanel(sailingService, this, getStringMessages());
|
||||
IgtimiAccountsPanel igtimiAccountsPanel = new IgtimiAccountsPanel(getSailingService(), this, getStringMessages());
|
||||
igtimiAccountsPanel.ensureDebugId("IgtimiAccounts");
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<IgtimiAccountsPanel>(igtimiAccountsPanel),
|
||||
getStringMessages().igtimiAccounts(), Permission.MANAGE_IGTIMI_ACCOUNTS);
|
||||
|
||||
ExpeditionDeviceConfigurationsPanel expeditionDeviceConfigurationsPanel = new ExpeditionDeviceConfigurationsPanel(sailingService, this, getStringMessages());
|
||||
ExpeditionDeviceConfigurationsPanel expeditionDeviceConfigurationsPanel = new ExpeditionDeviceConfigurationsPanel(getSailingService(), this, getStringMessages());
|
||||
expeditionDeviceConfigurationsPanel.ensureDebugId("ExpeditionDeviceConfigurations");
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<ExpeditionDeviceConfigurationsPanel>(expeditionDeviceConfigurationsPanel) {
|
||||
@Override
|
||||
@@ -258,11 +258,11 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
}
|
||||
}, getStringMessages().expeditionDeviceConfigurations(), Permission.MANAGE_EXPEDITION_DEVICE_CONFIGURATIONS);
|
||||
|
||||
ResultImportUrlsManagementPanel resultImportUrlsManagementPanel = new ResultImportUrlsManagementPanel(sailingService, this, getStringMessages());
|
||||
ResultImportUrlsManagementPanel resultImportUrlsManagementPanel = new ResultImportUrlsManagementPanel(getSailingService(), this, getStringMessages());
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<ResultImportUrlsManagementPanel>(resultImportUrlsManagementPanel),
|
||||
getStringMessages().resultImportUrls(), Permission.MANAGE_RESULT_IMPORT_URLS);
|
||||
|
||||
StructureImportManagementPanel structureImportUrlsManagementPanel = new StructureImportManagementPanel(sailingService, this, getStringMessages(), this, eventManagementPanel);
|
||||
StructureImportManagementPanel structureImportUrlsManagementPanel = new StructureImportManagementPanel(getSailingService(), this, getStringMessages(), this, eventManagementPanel);
|
||||
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<StructureImportManagementPanel>(structureImportUrlsManagementPanel),
|
||||
getStringMessages().manage2Sail() + " " + getStringMessages().regattaStructureImport(), Permission.MANAGE_STRUCTURE_IMPORT_URLS);
|
||||
|
||||
@@ -270,7 +270,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
|
||||
final HorizontalTabLayoutPanel advancedTabPanel = panel.addVerticalTab(getStringMessages().advanced(), "AdvancedPanel");
|
||||
advancedTabPanel.ensureDebugId("AdvancedTab");
|
||||
final ReplicationPanel replicationPanel = new ReplicationPanel(sailingService, this, getStringMessages());
|
||||
final ReplicationPanel replicationPanel = new ReplicationPanel(getSailingService(), this, getStringMessages());
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<ReplicationPanel>(replicationPanel) {
|
||||
@Override
|
||||
public void refreshAfterBecomingVisible() {
|
||||
@@ -278,17 +278,17 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
}
|
||||
}, getStringMessages().replication(), Permission.MANAGE_REPLICATION);
|
||||
|
||||
final MasterDataImportPanel masterDataImportPanel = new MasterDataImportPanel(getStringMessages(), sailingService,
|
||||
final MasterDataImportPanel masterDataImportPanel = new MasterDataImportPanel(getStringMessages(), getSailingService(),
|
||||
this, eventManagementPanel, this, this, mediaPanel);
|
||||
masterDataImportPanel.ensureDebugId("MasterDataImport");
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<MasterDataImportPanel>(masterDataImportPanel),
|
||||
getStringMessages().masterDataImportPanel(), Permission.MANAGE_MASTERDATA_IMPORT);
|
||||
|
||||
RemoteServerInstancesManagementPanel remoteServerInstancesManagementPanel = new RemoteServerInstancesManagementPanel(sailingService, this, getStringMessages());
|
||||
RemoteServerInstancesManagementPanel remoteServerInstancesManagementPanel = new RemoteServerInstancesManagementPanel(getSailingService(), this, getStringMessages());
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<RemoteServerInstancesManagementPanel>(remoteServerInstancesManagementPanel),
|
||||
getStringMessages().remoteServerInstances(), Permission.MANAGE_SAILING_SERVER_INSTANCES);
|
||||
|
||||
LocalServerManagementPanel localServerInstancesManagementPanel = new LocalServerManagementPanel(sailingService, this, getStringMessages());
|
||||
LocalServerManagementPanel localServerInstancesManagementPanel = new LocalServerManagementPanel(getSailingService(), this, getStringMessages());
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<LocalServerManagementPanel>(localServerInstancesManagementPanel),
|
||||
getStringMessages().localServer(), Permission.MANAGE_LOCAL_SERVER_INSTANCE);
|
||||
|
||||
@@ -297,7 +297,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<UserManagementPanel>(userManagementPanel),
|
||||
getStringMessages().userManagement(), Permission.MANAGE_USERS);
|
||||
|
||||
final FileStoragePanel fileStoragePanel = new FileStoragePanel(sailingService, this);
|
||||
final FileStoragePanel fileStoragePanel = new FileStoragePanel(getSailingService(), this);
|
||||
panel.addToTabPanel(advancedTabPanel, new DefaultRefreshableAdminConsolePanel<FileStoragePanel>(fileStoragePanel),
|
||||
getStringMessages().fileStorage(), Permission.MANAGE_FILE_STORAGE);
|
||||
|
||||
@@ -311,7 +311,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
|
||||
@Override
|
||||
public void fillLeaderboards() {
|
||||
sailingService.getLeaderboards(new MarkedAsyncCallback<List<StrippedLeaderboardDTO>>(
|
||||
getSailingService().getLeaderboards(new MarkedAsyncCallback<List<StrippedLeaderboardDTO>>(
|
||||
new AsyncCallback<List<StrippedLeaderboardDTO>>() {
|
||||
@Override
|
||||
public void onSuccess(List<StrippedLeaderboardDTO> leaderboards) {
|
||||
@@ -338,7 +338,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
|
||||
@Override
|
||||
public void fillLeaderboardGroups() {
|
||||
sailingService.getLeaderboardGroups(false /*withGeoLocationData*/,
|
||||
getSailingService().getLeaderboardGroups(false /*withGeoLocationData*/,
|
||||
new MarkedAsyncCallback<List<LeaderboardGroupDTO>>(
|
||||
new AsyncCallback<List<LeaderboardGroupDTO>>() {
|
||||
@Override
|
||||
@@ -366,7 +366,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
|
||||
|
||||
@Override
|
||||
public void fillRegattas() {
|
||||
sailingService.getRegattas(new MarkedAsyncCallback<List<RegattaDTO>>(
|
||||
getSailingService().getRegattas(new MarkedAsyncCallback<List<RegattaDTO>>(
|
||||
new AsyncCallback<List<RegattaDTO>>() {
|
||||
@Override
|
||||
public void onSuccess(List<RegattaDTO> result) {
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -334,7 +334,7 @@ TrackedRaceChangedListener, LeaderboardsDisplayer {
|
||||
});
|
||||
editCompetitorsDialog.show();
|
||||
} else if (LeaderboardConfigImagesBarCell.ACTION_CONFIGURE_URL.equals(value)) {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardDTO.name, new AsyncCallback<Iterable<DetailType>>() {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardDTO.name, null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
|
||||
+16
-2
@@ -23,12 +23,13 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.DeviceConfigurationDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.DeviceConfigurationDTO.RegattaConfigurationDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.DeviceConfigurationDTO.RegattaConfigurationDTO.RacingProcedureConfigurationDTO;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.gwt.client.controls.IntegerBox;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
|
||||
public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurationDTO.RegattaConfigurationDTO> {
|
||||
|
||||
private final AdminConsoleResources resources = GWT.create(AdminConsoleResources.class);
|
||||
|
||||
private final StringMessages stringMessages;
|
||||
private final DeviceConfigurationDTO.RegattaConfigurationDTO originalConfiguration;
|
||||
|
||||
@@ -36,6 +37,7 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
||||
|
||||
private ListBox racingProcedureListBox;
|
||||
private ListBox designerModeEntryListBox;
|
||||
private IntegerBox protestTimeInMinutesTextBox;
|
||||
|
||||
private DisclosurePanel rrs26DisclosurePanel;
|
||||
private CheckBox rrs26EnabledBox;
|
||||
@@ -118,9 +120,10 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
||||
}
|
||||
|
||||
private void setupGeneral() {
|
||||
Grid grid = new Grid(2, 2);
|
||||
Grid grid = new Grid(3, 2);
|
||||
setupCourseDesignerListBox(grid, 0);
|
||||
setupRacingProcedureListBox(grid, 1);
|
||||
setupProtestTimeTextBox(grid, 2);
|
||||
contentPanel.add(grid);
|
||||
}
|
||||
|
||||
@@ -155,6 +158,14 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
||||
grid.setWidget(gridRow, 1, designerModeEntryListBox);
|
||||
}
|
||||
|
||||
private void setupProtestTimeTextBox(Grid grid, int gridRow) {
|
||||
final Integer protestTimeDurationInMinutes = originalConfiguration.defaultProtestTimeDuration == null ? null :
|
||||
(int) originalConfiguration.defaultProtestTimeDuration.asMinutes();
|
||||
protestTimeInMinutesTextBox = createIntegerBox(protestTimeDurationInMinutes, 3);
|
||||
grid.setWidget(gridRow, 0, new Label(stringMessages.protestTime()));
|
||||
grid.setWidget(gridRow, 1, protestTimeInMinutesTextBox);
|
||||
}
|
||||
|
||||
private ListBox setupClassFlagListBox(RacingProcedureConfigurationDTO config) {
|
||||
ListBox box = createListBox(false);
|
||||
Flags selectedFlag = null;
|
||||
@@ -345,6 +356,7 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
||||
if (originalConfiguration.gateStartConfiguration != null) {
|
||||
gateStartGolfDownBox.setValue(originalConfiguration.gateStartConfiguration.hasAdditionalGolfDownTime);
|
||||
}
|
||||
|
||||
grid.setWidget(0, 0, new Label(stringMessages.classFlag() + ":"));
|
||||
grid.setWidget(0, 1, gateStartClassFlagListBox);
|
||||
grid.setWidget(0, 2, createHelpImage(stringMessages.classFlagHelpText("Gate Start")));
|
||||
@@ -500,6 +512,8 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
||||
CourseDesignerMode mode = CourseDesignerMode.valueOf(designerModeEntryListBox.getValue(index));
|
||||
result.defaultCourseDesignerMode = mode == CourseDesignerMode.UNKNOWN ? null : mode;
|
||||
}
|
||||
result.defaultProtestTimeDuration = protestTimeInMinutesTextBox.getValue() == null ? null :
|
||||
Duration.ONE_MINUTE.times(protestTimeInMinutesTextBox.getValue());
|
||||
if (rrs26EnabledBox.getValue()) {
|
||||
result.rrs26Configuration = new DeviceConfigurationDTO.RegattaConfigurationDTO.RRS26ConfigurationDTO();
|
||||
getRacingProcedureConfigurationResults(result.rrs26Configuration, rrs26ClassFlagListBox, rrs26RecallBox, rrs26ResultEntryBox);
|
||||
|
||||
+99
-90
@@ -12,7 +12,6 @@ import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ChangeHandler;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
import com.google.gwt.user.cellview.client.Column;
|
||||
import com.google.gwt.user.cellview.client.ColumnSortEvent.Handler;
|
||||
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
|
||||
@@ -35,15 +34,15 @@ import com.sap.sailing.domain.common.RegattaName;
|
||||
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.controls.FlushableCellTable;
|
||||
import com.sap.sailing.gwt.ui.client.shared.controls.SelectionCheckboxColumn;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingConfigurationDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingEventRecordDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SwissTimingRaceRecordDTO;
|
||||
import com.sap.sse.common.util.NaturalComparator;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.celltable.BaseCelltable;
|
||||
import com.sap.sse.gwt.client.celltable.EntityIdentityComparator;
|
||||
import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel;
|
||||
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
|
||||
|
||||
/**
|
||||
@@ -55,9 +54,11 @@ import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
|
||||
*
|
||||
*/
|
||||
public class SwissTimingEventManagementPanel extends AbstractEventManagementPanel {
|
||||
private static final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
|
||||
|
||||
private final LabeledAbstractFilterablePanel<SwissTimingRaceRecordDTO> filterablePanelEvents;
|
||||
private final ListDataProvider<SwissTimingRaceRecordDTO> raceList;
|
||||
private final CellTable<SwissTimingRaceRecordDTO> raceTable;
|
||||
private final FlushableCellTable<SwissTimingRaceRecordDTO> raceTable;
|
||||
private final Map<String, SwissTimingConfigurationDTO> previousConfigurations;
|
||||
private final ListBox previousConfigurationsComboBox;
|
||||
private final TextBox jsonUrlBox;
|
||||
@@ -128,63 +129,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
fillRaces(sailingService);
|
||||
}
|
||||
});
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceNameColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.getName();
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> regattaNameColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.regattaName;
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> seriesNameColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.seriesName;
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceIdColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.raceId;
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> boatClassColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.boatClass != null ? object.boatClass : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> genderColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.gender != null ? object.gender : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceStatusColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.raceStatus != null ? object.raceStatus : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceStartTimeColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.raceStartTime==null?"":dateFormatter.render(object.raceStartTime) + " " + timeFormatter.render(object.raceStartTime);
|
||||
}
|
||||
};
|
||||
|
||||
HorizontalPanel racesSplitPanel = new HorizontalPanel();
|
||||
mainPanel.add(racesSplitPanel);
|
||||
|
||||
@@ -236,7 +181,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
useInternalMarkPassingAlgorithmCheckbox.setWordWrap(false);
|
||||
useInternalMarkPassingAlgorithmCheckbox.setValue(Boolean.FALSE);
|
||||
trackableRacesPanel.add(useInternalMarkPassingAlgorithmCheckbox);
|
||||
|
||||
|
||||
// text box for filtering the cell table
|
||||
HorizontalPanel filterPanel = new HorizontalPanel();
|
||||
filterPanel.setSpacing(5);
|
||||
@@ -246,23 +191,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
filterPanel.add(lblFilterEvents);
|
||||
filterPanel.setCellVerticalAlignment(lblFilterEvents, HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
|
||||
raceNameColumn.setSortable(true);
|
||||
raceStartTimeColumn.setSortable(true);
|
||||
boatClassColumn.setSortable(true);
|
||||
raceIdColumn.setSortable(true);
|
||||
genderColumn.setSortable(true);
|
||||
raceStatusColumn.setSortable(true);
|
||||
|
||||
AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
|
||||
raceTable = new BaseCelltable<SwissTimingRaceRecordDTO>(/* pageSize */10000, tableRes);
|
||||
raceTable.addColumn(regattaNameColumn, stringConstants.regatta());
|
||||
raceTable.addColumn(seriesNameColumn, stringConstants.series());
|
||||
raceTable.addColumn(raceNameColumn, stringConstants.name());
|
||||
//raceTable.addColumn(raceIdColumn, stringConstants.id());
|
||||
raceTable.addColumn(raceStatusColumn, stringConstants.status());
|
||||
raceTable.addColumn(boatClassColumn, stringConstants.boatClass());
|
||||
raceTable.addColumn(genderColumn, "Gender");
|
||||
raceTable.addColumn(raceStartTimeColumn, stringConstants.startTime());
|
||||
raceTable = new FlushableCellTable<SwissTimingRaceRecordDTO>(/* pageSize */10000, tableRes);
|
||||
raceTable.setWidth("300px");
|
||||
raceList = new ListDataProvider<SwissTimingRaceRecordDTO>();
|
||||
filterablePanelEvents = new LabeledAbstractFilterablePanel<SwissTimingRaceRecordDTO>(lblFilterEvents,
|
||||
@@ -282,19 +211,99 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
return strings;
|
||||
}
|
||||
};
|
||||
raceTable.setSelectionModel(new RefreshableMultiSelectionModel<SwissTimingRaceRecordDTO>(
|
||||
new EntityIdentityComparator<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public boolean representSameEntity(SwissTimingRaceRecordDTO dto1, SwissTimingRaceRecordDTO dto2) {
|
||||
return dto1.raceId.equals(dto2.raceId);
|
||||
}
|
||||
@Override
|
||||
public int hashCode(SwissTimingRaceRecordDTO t) {
|
||||
return t.raceId.hashCode();
|
||||
}
|
||||
}, filterablePanelEvents.getAllListDataProvider()) {
|
||||
});
|
||||
|
||||
final EntityIdentityComparator<SwissTimingRaceRecordDTO> entityIdentityComparator = new EntityIdentityComparator<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public boolean representSameEntity(SwissTimingRaceRecordDTO dto1, SwissTimingRaceRecordDTO dto2) {
|
||||
return dto1.raceId.equals(dto2.raceId);
|
||||
}
|
||||
@Override
|
||||
public int hashCode(SwissTimingRaceRecordDTO t) {
|
||||
return t.raceId.hashCode();
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceNameColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.getName();
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> regattaNameColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.regattaName;
|
||||
}
|
||||
};
|
||||
|
||||
SelectionCheckboxColumn<SwissTimingRaceRecordDTO> selectionColumn = new SelectionCheckboxColumn<SwissTimingRaceRecordDTO>(
|
||||
tableRes.cellTableStyle().cellTableCheckboxSelected(),
|
||||
tableRes.cellTableStyle().cellTableCheckboxDeselected(),
|
||||
tableRes.cellTableStyle().cellTableCheckboxColumnCell(), entityIdentityComparator, raceList, raceTable);
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> seriesNameColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.seriesName;
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceIdColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.raceId;
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> boatClassColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.boatClass != null ? object.boatClass : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> genderColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.gender != null ? object.gender : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceStatusColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.raceStatus != null ? object.raceStatus : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<SwissTimingRaceRecordDTO> raceStartTimeColumn = new TextColumn<SwissTimingRaceRecordDTO>() {
|
||||
@Override
|
||||
public String getValue(SwissTimingRaceRecordDTO object) {
|
||||
return object.raceStartTime==null?"":dateFormatter.render(object.raceStartTime) + " " + timeFormatter.render(object.raceStartTime);
|
||||
}
|
||||
};
|
||||
|
||||
raceNameColumn.setSortable(true);
|
||||
raceStartTimeColumn.setSortable(true);
|
||||
boatClassColumn.setSortable(true);
|
||||
raceIdColumn.setSortable(true);
|
||||
genderColumn.setSortable(true);
|
||||
raceStatusColumn.setSortable(true);
|
||||
|
||||
|
||||
raceTable.addColumn(selectionColumn, selectionColumn.getHeader());
|
||||
raceTable.addColumn(regattaNameColumn, stringConstants.regatta());
|
||||
raceTable.addColumn(seriesNameColumn, stringConstants.series());
|
||||
raceTable.addColumn(raceNameColumn, stringConstants.name());
|
||||
//raceTable.addColumn(raceIdColumn, stringConstants.id());
|
||||
raceTable.addColumn(raceStatusColumn, stringConstants.status());
|
||||
raceTable.addColumn(boatClassColumn, stringConstants.boatClass());
|
||||
raceTable.addColumn(genderColumn, "Gender");
|
||||
raceTable.addColumn(raceStartTimeColumn, stringConstants.startTime());
|
||||
|
||||
raceTable.setSelectionModel(selectionColumn.getSelectionModel(), selectionColumn.getSelectionManager());
|
||||
|
||||
trackableRacesPanel.add(raceTable);
|
||||
raceList.addDataDisplay(raceTable);
|
||||
Handler columnSortHandler = getRaceTableColumnSortHandler(raceList.getList(), regattaNameColumn, seriesNameColumn,
|
||||
|
||||
+20
-5
@@ -1,17 +1,32 @@
|
||||
package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.sap.sse.gwt.client.EntryPointHelper;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sse.gwt.client.ServiceRoutingProvider;
|
||||
import com.sap.sse.security.ui.client.AbstractSecureEntryPoint;
|
||||
|
||||
public abstract class AbstractSailingEntryPoint extends AbstractSecureEntryPoint<StringMessages> {
|
||||
protected final SailingServiceAsync sailingService = GWT.create(SailingService.class);
|
||||
private SailingServiceAsync sailingService;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) sailingService, RemoteServiceMappingConstants.sailingServiceRemotePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily initialize sailing service. Concrete entry point subclasses may influence sailing service creation by
|
||||
* implementing a given routing information providing interface {@link ProvidesLeaderboardRouting}. The routing
|
||||
* information provided via {@link ProvidesLeaderboardRouting#getLeaderboardName()} needs to be available when this
|
||||
* method is called for the first time. Repetitive calls will not cause a new leaderboard name to take effect.
|
||||
*/
|
||||
protected SailingServiceAsync getSailingService() {
|
||||
if (sailingService == null) {
|
||||
if (this instanceof ServiceRoutingProvider) {
|
||||
sailingService = SailingServiceHelper.createSailingServiceInstance((ServiceRoutingProvider)this);
|
||||
} else {
|
||||
sailingService = SailingServiceHelper.createSailingServiceInstance();
|
||||
}
|
||||
}
|
||||
return sailingService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-1
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sse.gwt.client.mvp.ClientFactory;
|
||||
import com.sap.sse.gwt.client.mvp.ErrorView;
|
||||
import com.sap.sse.security.ui.client.WithSecurity;
|
||||
@@ -11,9 +12,12 @@ import com.sap.sse.security.ui.client.WithSecurity;
|
||||
*
|
||||
*/
|
||||
public interface SailingClientFactory extends ClientFactory, WithSecurity {
|
||||
|
||||
SailingServiceAsync getSailingService();
|
||||
|
||||
SailingServiceAsync getSailingService(ProvidesLeaderboardRouting routingProvider);
|
||||
|
||||
MediaServiceAsync getMediaService();
|
||||
|
||||
|
||||
ErrorView createErrorView(String errorMessage, Throwable errorReason);
|
||||
}
|
||||
+7
-4
@@ -54,7 +54,7 @@ import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.impl.PreciseCompactGPSFixMovingImpl.PreciseCompactPosition;
|
||||
import com.sap.sailing.domain.common.windfinder.SpotDTO;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration;
|
||||
@@ -539,7 +539,7 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
|
||||
RaceCourseDTO getLastCourseDefinitionInRaceLog(String leaderboardName, String raceColumnName, String fleetName) throws NotFoundException;
|
||||
|
||||
/**
|
||||
* Adds a fix to the {@link GPSFixStore}, and creates a mapping with a virtual device for exactly the current
|
||||
* Adds a fix to the {@link SensorFixStore}, and creates a mapping with a virtual device for exactly the current
|
||||
* timepoint.
|
||||
*
|
||||
* @param timePoint
|
||||
@@ -756,7 +756,7 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
|
||||
|
||||
List<String> getRaceDisplayNamesFromLeaderboard(String leaderboardName, List<String> raceColumnNames) throws NotFoundException;
|
||||
|
||||
Iterable<DetailType> getAvailableDetailTypesForLeaderboard(String leaderboardName);
|
||||
Iterable<DetailType> getAvailableDetailTypesForLeaderboard(String leaderboardName, RegattaAndRaceIdentifier raceOrNull);
|
||||
|
||||
SpotDTO getWindFinderSpot(String spotId) throws Exception;
|
||||
|
||||
@@ -778,5 +778,8 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
|
||||
*/
|
||||
SliceRacePreperationDTO prepareForSlicingOfRace(RegattaAndRaceIdentifier raceIdentifier);
|
||||
|
||||
Boolean checkIfRaceIsTracked(RegattaAndRaceIdentifier race);
|
||||
/**
|
||||
* Checks if the given race is currently in state tracking or loading.
|
||||
*/
|
||||
Boolean checkIfRaceIsTracking(RegattaAndRaceIdentifier race);
|
||||
}
|
||||
+5
-2
@@ -965,7 +965,7 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
|
||||
|
||||
void getRaceDisplayNamesFromLeaderboard(final String leaderboardName, List<String> raceColumnNames, AsyncCallback<List<String>> callback);
|
||||
|
||||
void getAvailableDetailTypesForLeaderboard(String leaderboardName,
|
||||
void getAvailableDetailTypesForLeaderboard(String leaderboardName, RegattaAndRaceIdentifier raceOrNull,
|
||||
AsyncCallback<Iterable<DetailType>> asyncCallback);
|
||||
|
||||
void canSliceRace(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback<Boolean> callback);
|
||||
@@ -985,5 +985,8 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
|
||||
*/
|
||||
void getWindFinderSpot(String spotId, AsyncCallback<SpotDTO> callback);
|
||||
|
||||
void checkIfRaceIsTracked(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback<Boolean> asyncCallback);
|
||||
/**
|
||||
* @see SailingService#checkIfRaceIsTracking(RegattaAndRaceIdentifier)
|
||||
*/
|
||||
void checkIfRaceIsTracking(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback<Boolean> asyncCallback);
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.sap.sse.gwt.client.ServiceRoutingProvider;
|
||||
|
||||
/**
|
||||
* Set of convenience factory methods that create a {@link SailingServiceAsync} instance.
|
||||
*/
|
||||
public abstract class SailingServiceHelper {
|
||||
private final static String moduleBaseURL = GWT.getModuleBaseURL();
|
||||
|
||||
private SailingServiceHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SailingServiceAsync} instance, should be used when code resides in the same bundle as the sailing service code.
|
||||
*/
|
||||
public static SailingServiceAsync createSailingServiceInstance() {
|
||||
return createSailingServiceInstance(true, null);
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link SailingServiceAsync} instance.
|
||||
*
|
||||
* @param sameBundle {@code false} if using {@link SailingService} from a different OSGi bundle (e.g. dashboards), {@code true} otherwise
|
||||
*/
|
||||
public static SailingServiceAsync createSailingServiceInstance(boolean sameBundle) {
|
||||
return createSailingServiceInstance(sameBundle, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SailingServiceAsync} instance that uses a routing provider, for code in same bundle.
|
||||
*/
|
||||
public static SailingServiceAsync createSailingServiceInstance(ServiceRoutingProvider routingProvider) {
|
||||
return createSailingServiceInstance(true, routingProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crates a new {@link SailingServiceAsync} instance.
|
||||
*
|
||||
* @param sameBundle {@code false} if using {@link SailingService} from a different OSGi bundle (e.g. dashboards), {@code true} otherwise
|
||||
*/
|
||||
public static SailingServiceAsync createSailingServiceInstance(boolean sameBundle, ServiceRoutingProvider routingProvider) {
|
||||
SailingServiceAsync service = GWT.create(SailingService.class);
|
||||
ServiceDefTarget serviceToRegister = (ServiceDefTarget) service;
|
||||
StringBuilder baseURL = new StringBuilder();
|
||||
baseURL.append(moduleBaseURL.substring(0, moduleBaseURL.lastIndexOf('/', moduleBaseURL.length() - 2) + 1));
|
||||
if (!sameBundle) {
|
||||
baseURL.append(RemoteServiceMappingConstants.WEB_CONTEXT_PATH).append("/");
|
||||
}
|
||||
|
||||
baseURL.append(RemoteServiceMappingConstants.sailingServiceRemotePath);
|
||||
|
||||
if (routingProvider != null) {
|
||||
baseURL.append(routingProvider.routingSuffixPath());
|
||||
}
|
||||
serviceToRegister.setServiceEntryPoint(baseURL.toString());
|
||||
return service;
|
||||
}
|
||||
}
|
||||
+2
@@ -2076,4 +2076,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
|
||||
String multiUrlChangeNewURL();
|
||||
String multiUrlNoPrefixWarning();
|
||||
String multiUrlChangeExplain();
|
||||
String lastEvent(String locationOrVenue);
|
||||
String teaserOverallLinkToolTip();
|
||||
}
|
||||
+4
-2
@@ -1870,7 +1870,7 @@ anniversaryMajorCountdownTeaser[one]=Countdown! Only {0,number,#,###} race left
|
||||
anniversaryMajorCountdownDescription=We are celebrating our {0,number,#,###}th race on www.sapsailing.com! Which race will break the mark? The organizer of this anniversary race will receive a total sum of 10,000 Euro for charity purposes. The winner will be announced on this website. Stay tuned and count with us.
|
||||
anniversaryRepdigitCountdownTeaser=Countdown! Only {0,number,#,###} races left until the {1,number,#,###}th race.
|
||||
anniversaryRepdigitCountdownTeaser[one]=Countdown! Only {0,number,#,###} race left until the {1,number,#,###}th race.
|
||||
anniversaryRepdigitCountdownDescription=We are celebrating our lucky number races! Who will make the {0,number, #,###}th race on www.sapsailing.com? The participants of this race will get a free top-class summer festival from SAP. The winners will be announced on this website. Stay tuned and count with us.
|
||||
anniversaryRepdigitCountdownDescription=We are celebrating our lucky number races! Who will make the {0,number, #,###}th race on www.sapsailing.com? The organizers will get a free barbecue with drinks. The winners will be announced on this website. Stay tuned and count with us.
|
||||
anniversaryAnnouncementTeaser=Mission accomplished! {0,number,#,###} races with SAP Sailing Analytics!
|
||||
anniversaryAnnouncementDescription= 3,2,1... We congratulate the participants of the race {0}. You did it! We thank you for your trust in SAP Sailing Analytics and hopefully continue sailing some more 10,000 races with you!
|
||||
anniversaryRaceLinkText=Show anniversary race
|
||||
@@ -2069,4 +2069,6 @@ multiUrlChangeCannotSave=An error occured while saving
|
||||
multiUrlChangeSave=Save url changes
|
||||
multiUrlChangeNewURL=new url
|
||||
multiUrlNoPrefixWarning=No common prefix was found, this usually means that not all selected videos are hosted at the same location currently. Proceed at own risk!
|
||||
multiUrlChangeExplain=This dialog will bulk replace common parts at the start of mediatrack urls. Make sure all urls start with the same prefix! Also please take a look at the new url column, and test the resulting urls before pressing save!
|
||||
multiUrlChangeExplain=This dialog will bulk replace common parts at the start of mediatrack urls. Make sure all urls start with the same prefix! Also please take a look at the new url column, and test the resulting urls before pressing save!
|
||||
lastEvent=Last Event: {0}
|
||||
teaserOverallLinkToolTip=To see the overall series, click the yellow corner
|
||||
+4
-2
@@ -1876,7 +1876,7 @@ anniversaryMajorCountdownTeaser[one]=Countdown! Noch {0,number,#,###} Rennen bis
|
||||
anniversaryMajorCountdownDescription=Wir zelebrieren unser {0,number,#,###}. Rennen auf www.sapsailing.com! Welches Rennen schafft es die Marke zu durchbrechen? Der Veranstalter des Jubiläumsrennens erhält insgesamt 10.000 Euro für Wohltätigkeitszwecke. Der Gewinner wird auf der Website bekannt gegeben. Stay tuned.
|
||||
anniversaryRepdigitCountdownTeaser=Countdown! Noch {0,number,#,###} Rennen bis zum {1,number,#,###}. Rennen.
|
||||
anniversaryRepdigitCountdownTeaser[one]=Countdown! Noch {0,number,#,###} Rennen bis zum {1,number,#,###}. Rennen.
|
||||
anniversaryRepdigitCountdownDescription=Wir zelebrieren unsere Schnapszahlenrennen! Wer schafft es das {0,number,#,###}. Rennen zu machen? Dem Gewinner schenkt SAP ein Sommerfest der Extraklasse! Der Gewinner wird auf der Website bekannt gegeben. Stay tuned.
|
||||
anniversaryRepdigitCountdownDescription=Wir zelebrieren unsere Schnapszahlenrennen! Wer schafft es, das {0,number,#,###}. Rennen zu machen? Den Veranstaltern schenkt SAP ein kostenloses Barbecue mit Getränken. Der Gewinner wird auf der Website bekannt gegeben. Stay tuned.
|
||||
anniversaryAnnouncementTeaser=Mission erfüllt! {0,number,#,###} Rennen mit SAP Sailing Analytics!
|
||||
anniversaryAnnouncementDescription=3,2,1... Wir gratulieren den Teilnehmern des Rennens {0}. Ihr habt es geschafft die Marke zu durchbrechen. Wir danken euch für euer Vertrauen in SAP Sailing Analytics und hoffen, dass wir noch viele weitere Rennen mit euch machen werden!
|
||||
anniversaryRaceLinkText=Jubiläumsrennen anzeigen
|
||||
@@ -2065,4 +2065,6 @@ multiUrlChangeCannotSave=Es ist ein Fehler beim Speichern aufgetreten
|
||||
multiUrlChangeSave=Änderungen der URLs speichern
|
||||
multiUrlChangeNewURL=Neue Url
|
||||
multiUrlNoPrefixWarning=Es wurde kein gemeinsamer Präfix gefunden, dies deutet darauf hin, dass nicht alle ausgewählten Videos vom gleichen Host kommen. Auf eigene Gefahr fortsetzen!
|
||||
multiUrlChangeExplain=Dieser Dialog ermöglicht es, mehrere URL-Anfänge gleichzeitig auszutauschen. Hierzu müssen diese den gleichen Präfix besitzen. Bitte unbedingt die Spalte mit den neuen URLs beachten und diese testen bevor gespeichert wird!
|
||||
multiUrlChangeExplain=Dieser Dialog ermöglicht es, mehrere URL-Anfänge gleichzeitig auszutauschen. Hierzu müssen diese den gleichen Präfix besitzen. Bitte unbedingt die Spalte mit den neuen URLs beachten und diese testen bevor gespeichert wird!
|
||||
lastEvent=Letztes Event: {0}
|
||||
teaserOverallLinkToolTip=Um die Serien-Übersicht zu sehen, in die gelbe Ecke klicken
|
||||
+47
-49
@@ -13,6 +13,8 @@ import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ChangeHandler;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.media.client.Audio;
|
||||
import com.google.gwt.media.client.MediaBase;
|
||||
import com.google.gwt.typedarrays.shared.Int8Array;
|
||||
@@ -40,6 +42,8 @@ import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
|
||||
import com.sap.sse.gwt.client.controls.datetime.DateAndTimeInput;
|
||||
import com.sap.sse.gwt.client.controls.datetime.DateTimeInput.Accuracy;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
|
||||
public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
@@ -63,7 +67,7 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
|
||||
private TextBox titleBox;
|
||||
|
||||
protected TextBox startTimeBox;
|
||||
protected DateAndTimeInput startTimeBox;
|
||||
|
||||
private SimplePanel infoLabel; // showing either mime type or youtube id
|
||||
|
||||
@@ -83,6 +87,7 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
private Button defaultTimeButton;
|
||||
|
||||
private SimpleBusyIndicator busyIndicator;
|
||||
boolean manuallyEditedStartTime = false;
|
||||
|
||||
public NewMediaDialog(MediaServiceAsync mediaService, TimePoint defaultStartTime, StringMessages stringMessages,
|
||||
RegattaAndRaceIdentifier raceIdentifier, DialogCallback<MediaTrack> dialogCallback) {
|
||||
@@ -98,39 +103,16 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
@Override
|
||||
protected MediaTrack getResult() {
|
||||
mediaTrack.title = titleBox.getValue();
|
||||
updateStartTimeFromUi();
|
||||
updateDurationFromUi();
|
||||
connectMediaWithRace();
|
||||
return mediaTrack;
|
||||
}
|
||||
|
||||
private void updateDurationFromUi() {
|
||||
String duration = durationBox.getValue();
|
||||
if (duration != null && !duration.trim().isEmpty()) {
|
||||
mediaTrack.duration = TimeFormatUtil.hrsMinSecToMilliSeconds(duration);
|
||||
} else {
|
||||
mediaTrack.duration = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void connectMediaWithRace() {
|
||||
Set<RegattaAndRaceIdentifier> assignedRaces = new HashSet<RegattaAndRaceIdentifier>();
|
||||
assignedRaces.add(this.raceIdentifier);
|
||||
mediaTrack.assignedRaces = assignedRaces;
|
||||
}
|
||||
|
||||
protected void updateStartTimeFromUi() {
|
||||
String startTimeText = startTimeBox.getValue();
|
||||
if (startTimeText != null && !startTimeText.equals("")) {
|
||||
try {
|
||||
Date startTime = TimeFormatUtil.DATETIME_FORMAT.parse(startTimeText);
|
||||
mediaTrack.startTime = new MillisecondsTimePoint(startTime);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// TODO: highlight format error in UI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMediaDuration() {
|
||||
MediaBase mediaBase = Audio.createIfSupported();
|
||||
if (mediaBase != null) {
|
||||
@@ -150,7 +132,9 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
}-*/;
|
||||
|
||||
public void loadedmetadata(MediaElement mediaElement) {
|
||||
mediaTrack.startTime = this.defaultStartTime;
|
||||
if (!manuallyEditedStartTime) {
|
||||
mediaTrack.startTime = this.defaultStartTime;
|
||||
}
|
||||
double duration = mediaElement.getDuration();
|
||||
if (duration > 0) {
|
||||
mediaTrack.duration = new MillisecondsDurationImpl((long) Math.round(duration * 1000));
|
||||
@@ -166,7 +150,19 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
Grid formGrid = new Grid(6, 2);
|
||||
formGrid.setCellSpacing(3);
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.url() + ":"));
|
||||
urlBox = createUrlBox();
|
||||
urlBox = createTextBox(null);
|
||||
urlBox.addChangeHandler(new ChangeHandler() {
|
||||
@Override
|
||||
public void onChange(ChangeEvent event) {
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
manuallyEditedStartTime = false;
|
||||
updateFromUrl();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
formGrid.setWidget(0, 1, urlBox);
|
||||
formGrid.setWidget(1, 0, new Label(stringMessages.name() + ":"));
|
||||
titleBox = createTextBox(null);
|
||||
@@ -177,13 +173,23 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
infoLabel.setWidget(new Label(""));
|
||||
formGrid.setWidget(2, 1, infoLabel);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.startTime() + ":"));
|
||||
startTimeBox = createTextBox(null);
|
||||
|
||||
startTimeBox = new DateAndTimeInput(Accuracy.MILLISECONDS);
|
||||
FlowPanel startTimePanel = new FlowPanel();
|
||||
startTimePanel.add(startTimeBox);
|
||||
startTimeBox.addValueChangeHandler(new ValueChangeHandler<Date>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Date> event) {
|
||||
manuallyEditedStartTime = true;
|
||||
mediaTrack.startTime = new MillisecondsTimePoint(event.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
defaultTimeButton = new Button(StringMessages.INSTANCE.resetStartTimeToDefault());
|
||||
defaultTimeButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
manuallyEditedStartTime = true;
|
||||
mediaTrack.startTime = defaultStartTime;
|
||||
refreshUI();
|
||||
}
|
||||
@@ -192,6 +198,17 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
formGrid.setWidget(3, 1, startTimePanel);
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.duration() + ":"));
|
||||
durationBox = createTextBox(null);
|
||||
durationBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
String duration = durationBox.getValue();
|
||||
if (duration != null && !duration.trim().isEmpty()) {
|
||||
mediaTrack.duration = TimeFormatUtil.hrsMinSecToMilliSeconds(duration);
|
||||
} else {
|
||||
mediaTrack.duration = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
formGrid.setWidget(4, 1, durationBox);
|
||||
busyIndicator = new SimpleBusyIndicator();
|
||||
formGrid.setWidget(5, 0, busyIndicator);
|
||||
@@ -199,22 +216,6 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private TextBox createUrlBox() {
|
||||
TextBox result = createTextBox(null);
|
||||
result.addChangeHandler(new ChangeHandler() {
|
||||
@Override
|
||||
public void onChange(ChangeEvent event) {
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
updateFromUrl();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void updateFromUrl() {
|
||||
String url = urlBox.getValue();
|
||||
String youtubeId = YoutubeApi.getIdByUrl(url);
|
||||
@@ -315,7 +316,7 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
refreshUI();
|
||||
}
|
||||
|
||||
private void refreshUI() {
|
||||
protected void refreshUI() {
|
||||
titleBox.setValue(mediaTrack.title, DONT_FIRE_EVENTS);
|
||||
if (mediaTrack.isYoutube()) {
|
||||
infoLabelLabel.setText(stringMessages.youtubeId() + ":");
|
||||
@@ -335,10 +336,7 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
}
|
||||
}
|
||||
TimePoint startTime = mediaTrack.startTime != null ? mediaTrack.startTime : defaultStartTime;
|
||||
String startTimeText = TimeFormatUtil.DATETIME_FORMAT.format(startTime.asDate());
|
||||
|
||||
startTimeBox.setText(startTimeText);
|
||||
updateStartTimeFromUi();
|
||||
startTimeBox.setValue(startTime == null ? null : startTime.asDate());
|
||||
if (mediaTrack.duration != null) {
|
||||
durationBox.setText(TimeFormatUtil.durationToHrsMinSec(mediaTrack.duration));
|
||||
} else {
|
||||
@@ -439,7 +437,7 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
|
||||
} else {
|
||||
mediaTrack.duration = result.getDuration();
|
||||
mediaTrack.mimeType = result.isSpherical() ? MimeType.mp4panorama : MimeType.mp4;
|
||||
if (result.getRecordStartedTime() != null) {
|
||||
if (result.getRecordStartedTime() != null && !manuallyEditedStartTime) {
|
||||
mediaTrack.startTime = new MillisecondsTimePoint(result.getRecordStartedTime());
|
||||
}
|
||||
refreshUI();
|
||||
|
||||
+16
-14
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.gwt.ui.client.media;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
@@ -13,7 +14,6 @@ import com.sap.sailing.gwt.ui.client.RegattasDisplayer;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
|
||||
public class NewMediaWithRaceSelectionDialog extends NewMediaDialog {
|
||||
@@ -41,19 +41,7 @@ public class NewMediaWithRaceSelectionDialog extends NewMediaDialog {
|
||||
this.regattasDisplayers = regattasDisplayers;
|
||||
}
|
||||
|
||||
protected void updateStartTimeFromUi() {
|
||||
try {
|
||||
String startTime = startTimeBox.getValue();
|
||||
if (startTime != null && !startTime.equals("")) {
|
||||
mediaTrack.startTime = new MillisecondsTimePoint(TimeFormatUtil.DATETIME_FORMAT.parse(startTime));
|
||||
regattaRefresher.fillRegattas();
|
||||
listOfRacesForMedia.setVisible(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
listOfRacesForMedia.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void connectMediaWithRace() {
|
||||
mediaTrack.assignedRaces = racesForMediaDialog.getAssignedRaces();
|
||||
}
|
||||
@@ -81,6 +69,7 @@ public class NewMediaWithRaceSelectionDialog extends NewMediaDialog {
|
||||
return listOfRacesForMedia = racesForMediaDialog.getAdditionalWidget();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget getAdditionalWidget() {
|
||||
VerticalPanel mainPanel = (VerticalPanel) super.getAdditionalWidget();
|
||||
mainPanel.add(racesForMedia());
|
||||
@@ -88,4 +77,17 @@ public class NewMediaWithRaceSelectionDialog extends NewMediaDialog {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refreshUI() {
|
||||
super.refreshUI();
|
||||
try {
|
||||
Date value = startTimeBox.getValue();
|
||||
if (value != null) {
|
||||
regattaRefresher.fillRegattas();
|
||||
listOfRacesForMedia.setVisible(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
listOfRacesForMedia.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
+79
-57
@@ -114,7 +114,6 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
private LinePlotOptions markSeriesPlotOptions;
|
||||
private final Label noMarkSelectedLabel;
|
||||
private MapWidget map;
|
||||
private boolean visible;
|
||||
private List<HandlerRegistration> courseMarkClickHandlers;
|
||||
|
||||
private Map<MarkDTO, Pair<Date, Date>> marksFromToTimes;
|
||||
@@ -131,6 +130,7 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
private final MarkPositionService markPositionService;
|
||||
|
||||
private final RaceIdentifierToLeaderboardRaceColumnAndFleetMapper raceIdentifierToLeaderboardRaceColumnAndFleetMapper;
|
||||
protected boolean nonTrackingWarningWasDisplayed;
|
||||
|
||||
public EditMarkPositionPanel(Component<?> parent, ComponentContext<?> context, final RaceMap raceMap,
|
||||
final SingleRaceLeaderboardPanel leaderboardPanel,
|
||||
@@ -373,20 +373,25 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
overlay.setVisible(false);
|
||||
if (currentFixPositionChooser == null) {
|
||||
OverlayClickHandler.this.unregisterAll();
|
||||
currentFixPositionChooser = new FixPositionChooser(EditMarkPositionPanel.this, stringMessages, map, getIndexOfFixInPolyline(mark, fix), polyline.getPath(), overlay, new Callback<Position, Exception>() {
|
||||
@Override
|
||||
public void onFailure(Exception reason) {
|
||||
overlay.setVisible(true);
|
||||
OverlayClickHandler.this.registerAll();
|
||||
resetCurrentFixPositionChooser();
|
||||
}
|
||||
@Override
|
||||
public void onSuccess(Position result) {
|
||||
editMarkFix(mark, fix, result);
|
||||
overlay.setVisible(true);
|
||||
OverlayClickHandler.this.registerAll();
|
||||
resetCurrentFixPositionChooser();
|
||||
}
|
||||
checkIfTracking(() -> {
|
||||
currentFixPositionChooser = new FixPositionChooser(EditMarkPositionPanel.this,
|
||||
stringMessages, map, getIndexOfFixInPolyline(mark, fix), polyline.getPath(),
|
||||
overlay, new Callback<Position, Exception>() {
|
||||
@Override
|
||||
public void onFailure(Exception reason) {
|
||||
overlay.setVisible(true);
|
||||
OverlayClickHandler.this.registerAll();
|
||||
resetCurrentFixPositionChooser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Position result) {
|
||||
editMarkFix(mark, fix, result);
|
||||
overlay.setVisible(true);
|
||||
OverlayClickHandler.this.registerAll();
|
||||
resetCurrentFixPositionChooser();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
popup.hide();
|
||||
@@ -407,26 +412,28 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
}
|
||||
|
||||
private void addDeleteItemAndShowPopup(boolean enableDelete) {
|
||||
final MenuItem delete;
|
||||
Runnable r = () -> {
|
||||
final MenuItem delete = new MenuItem(stringMessages.deleteFix(), new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
if (enableDelete) {
|
||||
removeMarkFix(mark, fix);
|
||||
popup.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!enableDelete) {
|
||||
delete.setEnabled(false);
|
||||
delete.setTitle(stringMessages.theDeletionOfThisFix());
|
||||
}
|
||||
menu.addItem(delete);
|
||||
popup.setWidget(menu);
|
||||
};
|
||||
if (enableDelete) {
|
||||
delete = new MenuItem(stringMessages.deleteFix(), new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
removeMarkFix(mark, fix);
|
||||
popup.hide();
|
||||
}
|
||||
});
|
||||
checkIfTracking(r);
|
||||
} else {
|
||||
delete = new MenuItem(stringMessages.deleteFix(), new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
}
|
||||
});
|
||||
delete.setEnabled(false);
|
||||
delete.setTitle(stringMessages.theDeletionOfThisFix());
|
||||
r.run();
|
||||
}
|
||||
menu.addItem(delete);
|
||||
popup.setWidget(menu);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -704,20 +711,8 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
if(visible && !isVisible()){
|
||||
sailingService.checkIfRaceIsTracked(selectedRaceIdentifier, new AsyncCallback<Boolean>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
Window.alert(stringMessages.serverError());
|
||||
}
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
if (Boolean.FALSE.equals(result)) {
|
||||
Window.alert(stringMessages.positionEditOnNonTrackingRace());
|
||||
}
|
||||
}
|
||||
});
|
||||
if (visible && !isVisible()) {
|
||||
checkIfTracking(() -> {});
|
||||
}
|
||||
if (map == null) {
|
||||
map = raceMap.getMap();
|
||||
@@ -725,7 +720,7 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
setMap(map);
|
||||
}
|
||||
}
|
||||
if (this.visible) {
|
||||
if (visible) {
|
||||
if (sideBySideComponentViewer != null) {
|
||||
sideBySideComponentViewer.setLeftComponent(marksPanel);
|
||||
sideBySideComponentViewer.setLeftComponentToggleButtonVisible(false);
|
||||
@@ -756,7 +751,30 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
raceMap.unregisterAllCourseMarkInfoWindowClickHandlers();
|
||||
raceMap.registerAllCourseMarkInfoWindowClickHandlers();
|
||||
}
|
||||
super.setVisible(this.visible);
|
||||
super.setVisible(visible);
|
||||
}
|
||||
|
||||
private void checkIfTracking(Runnable continuation) {
|
||||
if (nonTrackingWarningWasDisplayed) {
|
||||
continuation.run();
|
||||
} else {
|
||||
sailingService.checkIfRaceIsTracking(selectedRaceIdentifier, new AsyncCallback<Boolean>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
Window.alert(stringMessages.serverError());
|
||||
continuation.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
if (Boolean.FALSE.equals(result)) {
|
||||
Window.alert(stringMessages.positionEditOnNonTrackingRace());
|
||||
nonTrackingWarningWasDisplayed = true;
|
||||
}
|
||||
continuation.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -943,17 +961,21 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
* Is thrown when another fix position chooser is still open
|
||||
*/
|
||||
public void createFixPositionChooserToAddFixToMark(MarkDTO mark, Callback<Position, Exception> callback) {
|
||||
if (currentFixPositionChooser != null) {
|
||||
if (currentFixPositionChooser != null) {
|
||||
return;
|
||||
}
|
||||
int index = 0;
|
||||
for (GPSFixDTO fix : marks.get(mark).keySet()) {
|
||||
if (fix.timepoint.after(timer.getTime()))
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
Polyline polyline = polylines.get(mark);
|
||||
currentFixPositionChooser = new FixPositionChooser(this, stringMessages, map, index, polyline != null ? polyline.getPath() : null, map.getCenter(), raceMap.getCoordinateSystem(), callback);
|
||||
checkIfTracking(() -> {
|
||||
int index = 0;
|
||||
for (GPSFixDTO fix : marks.get(mark).keySet()) {
|
||||
if (fix.timepoint.after(timer.getTime()))
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
Polyline polyline = polylines.get(mark);
|
||||
currentFixPositionChooser = new FixPositionChooser(EditMarkPositionPanel.this, stringMessages, map, index,
|
||||
polyline != null ? polyline.getPath() : null, map.getCenter(), raceMap.getCoordinateSystem(),
|
||||
callback);
|
||||
});
|
||||
}
|
||||
|
||||
public void resetCurrentFixPositionChooser() {
|
||||
|
||||
-6
@@ -50,12 +50,6 @@ public interface MarkPositionService {
|
||||
|
||||
void getMarksInTrackedRace(LeaderboardNameRaceColumnNameAndFleetName raceIdentifier, AsyncCallback<Iterable<MarkDTO>> callback);
|
||||
|
||||
// Jonas Dann: I had no great idea for handling of massive amount of fixes. An exception is no real option. I
|
||||
// think the fixes have to be thinned out somehow and maybe shown in more detail when zoomed in. The aggregation of
|
||||
// fixes is in my eyes no option, because then you have to define behaviour when moving them.
|
||||
// I had no remaining time to incorporate the thinned out variable in my code.
|
||||
void getMarkTracks(LeaderboardNameRaceColumnNameAndFleetName raceIdentifier, AsyncCallback<MarkTracksDTO> callback);
|
||||
|
||||
void getMarkTrack(LeaderboardNameRaceColumnNameAndFleetName raceIdentifier, String markIdAsString, AsyncCallback<MarkTrackDTO> callback);
|
||||
|
||||
/**
|
||||
|
||||
-5
@@ -20,11 +20,6 @@ public class MarkPositionServiceForSailingService implements MarkPositionService
|
||||
sailingService.getMarksInTrackedRace(raceIdentifier.getLeaderboardName(), raceIdentifier.getRaceColumnName(), raceIdentifier.getFleetName(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getMarkTracks(LeaderboardNameRaceColumnNameAndFleetName raceIdentifier, AsyncCallback<MarkTracksDTO> callback) {
|
||||
sailingService.getMarkTracks(raceIdentifier.getLeaderboardName(), raceIdentifier.getRaceColumnName(), raceIdentifier.getFleetName(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getMarkTrack(LeaderboardNameRaceColumnNameAndFleetName raceIdentifier, String markIdAsString,
|
||||
AsyncCallback<MarkTrackDTO> callback) {
|
||||
|
||||
+31
-49
@@ -6,6 +6,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.moxieapps.gwt.highcharts.client.Axis;
|
||||
@@ -226,65 +227,46 @@ public class WindChart extends AbstractRaceChart<WindChartSettings> implements R
|
||||
}
|
||||
|
||||
private void updateVisibleSeries() {
|
||||
List<Series> currentSeries = Arrays.asList(chart.getSeries());
|
||||
Set<Series> visibleSeries = new HashSet<Series>(currentSeries);
|
||||
final Set<Series> visibleSeries = new HashSet<Series>(Arrays.asList(chart.getSeries()));
|
||||
|
||||
if (preselectFilter != null) {
|
||||
forceSeriesSelection(visibleSeries, windSourceDirectionSeries);
|
||||
forceSeriesSelection(visibleSeries, windSourceSpeedSeries);
|
||||
} else {
|
||||
if (settings.isShowWindDirectionsSeries()) {
|
||||
for (Map.Entry<WindSource, Series> e : windSourceDirectionSeries.entrySet()) {
|
||||
Series series = e.getValue();
|
||||
if (settings.getWindDirectionSourcesToDisplay().contains(e.getKey().getType())) {
|
||||
if (!visibleSeries.contains(series)) {
|
||||
chart.addSeries(series, false, false);
|
||||
}
|
||||
series.select(true); // ensures that the checkbox will be ticked
|
||||
series.setVisible(true); //and that it is actually being rendered
|
||||
} else {
|
||||
if (visibleSeries.contains(series)) {
|
||||
chart.removeSeries(series, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<WindSource, Series> e : windSourceDirectionSeries.entrySet()) {
|
||||
Series series = e.getValue();
|
||||
if (visibleSeries.contains(series)) {
|
||||
chart.removeSeries(series, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.isShowWindSpeedSeries()) {
|
||||
for (Map.Entry<WindSource, Series> e : windSourceSpeedSeries.entrySet()) {
|
||||
Series series = e.getValue();
|
||||
if (settings.getWindSpeedSourcesToDisplay().contains(e.getKey().getType())) {
|
||||
if (!visibleSeries.contains(series)) {
|
||||
chart.addSeries(series, false, false);
|
||||
}
|
||||
series.select(true); // ensures that the checkbox will be ticked
|
||||
series.setVisible(true); //and that it is actually being rendered
|
||||
} else {
|
||||
if (visibleSeries.contains(series)) {
|
||||
chart.removeSeries(series, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<WindSource, Series> e : windSourceSpeedSeries.entrySet()) {
|
||||
Series series = e.getValue();
|
||||
if (visibleSeries.contains(series)) {
|
||||
chart.removeSeries(series, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
final boolean showDirectionSeries = settings.isShowWindDirectionsSeries();
|
||||
final Set<WindSourceType> directionSourceTypesToDisplay = settings.getWindDirectionSourcesToDisplay();
|
||||
updateSeries(visibleSeries, windSourceDirectionSeries, showDirectionSeries, directionSourceTypesToDisplay);
|
||||
final boolean showSpeedSeries = settings.isShowWindSpeedSeries();
|
||||
final Set<WindSourceType> speedSourceTypesToDisplay = settings.getWindSpeedSourcesToDisplay();
|
||||
updateSeries(visibleSeries, windSourceSpeedSeries, showSpeedSeries, speedSourceTypesToDisplay);
|
||||
}
|
||||
|
||||
onResize();
|
||||
}
|
||||
|
||||
private void updateSeries(final Set<Series> visibleSeries, final Map<WindSource, Series> windSourceToSeriesMap,
|
||||
final boolean showSeries, final Set<WindSourceType> windSourceTypesToDisplay) {
|
||||
if (showSeries) {
|
||||
for (Entry<WindSource, Series> entry : windSourceToSeriesMap.entrySet()) {
|
||||
final Series series = entry.getValue();
|
||||
if (windSourceTypesToDisplay.contains(entry.getKey().getType())) {
|
||||
if (!visibleSeries.contains(series)) {
|
||||
chart.addSeries(series, false, false);
|
||||
}
|
||||
} else if (visibleSeries.contains(series)) {
|
||||
chart.removeSeries(series, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Entry<WindSource, Series> entry : windSourceToSeriesMap.entrySet()) {
|
||||
final Series series = entry.getValue();
|
||||
if (visibleSeries.contains(series)) {
|
||||
chart.removeSeries(series, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean forceSeriesSelection(Set<Series> visibleSeries, Map<WindSource, Series> toProcess) {
|
||||
boolean wasInResult = false;
|
||||
for (Map.Entry<WindSource, Series> e : toProcess.entrySet()) {
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class BoatClassVectorGraphicsResolver {
|
||||
BoatClassMasterdata.TOM_28_MAX, BoatClassMasterdata.DELPHIA_24,
|
||||
BoatClassMasterdata.RS200, BoatClassMasterdata.RS400, BoatClassMasterdata.RS500, BoatClassMasterdata.RS800,
|
||||
BoatClassMasterdata.STREAMLINE, BoatClassMasterdata.SWAN_45, BoatClassMasterdata.TEENY, BoatClassMasterdata.X_99,
|
||||
BoatClassMasterdata.TRIAS, BoatClassMasterdata.VENT_D_OUEST);
|
||||
BoatClassMasterdata.TRIAS, BoatClassMasterdata.VENT_D_OUEST, BoatClassMasterdata.FLYING_JUNIOR);
|
||||
BoatClassVectorGraphics circle = new CircleVectorGraphics(BoatClassMasterdata.RUNNING);
|
||||
|
||||
defaultBoatVectorGraphics = dinghyWithSpinnaker; // TODO see bug 2571; this should be a slup-rigged icon working for 470, 505, J/70 etc.
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ public class ManeuverTableLifecycle implements ComponentLifecycle<ManeuverTableS
|
||||
|
||||
@Override
|
||||
public String getLocalizedShortName() {
|
||||
return stringMessages.wind();
|
||||
return stringMessages.maneuverTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-6
@@ -13,11 +13,10 @@ public class ManeuverTableSettings extends AbstractGenericSerializableSettings {
|
||||
|
||||
private EnumSetSetting<ManeuverType> selectedManeuverTypes;
|
||||
|
||||
private Iterable<ManeuverType> defaultTypes = Arrays.asList(ManeuverType.values());
|
||||
|
||||
@Override
|
||||
protected void addChildSettings() {
|
||||
selectedManeuverTypes = new EnumSetSetting<>("selectedManeuverTypes", this, defaultTypes,
|
||||
selectedManeuverTypes = new EnumSetSetting<>("selectedManeuverTypes", this,
|
||||
Arrays.asList(ManeuverType.TACK, ManeuverType.JIBE, ManeuverType.PENALTY_CIRCLE),
|
||||
ManeuverType::valueOf);
|
||||
}
|
||||
|
||||
@@ -25,9 +24,6 @@ public class ManeuverTableSettings extends AbstractGenericSerializableSettings {
|
||||
* The default settings
|
||||
*/
|
||||
public ManeuverTableSettings() {
|
||||
selectedManeuverTypes.addValue(ManeuverType.TACK);
|
||||
selectedManeuverTypes.addValue(ManeuverType.JIBE);
|
||||
selectedManeuverTypes.addValue(ManeuverType.PENALTY_CIRCLE);
|
||||
}
|
||||
|
||||
public ManeuverTableSettings(Set<ManeuverType> selectedManeuverTypes) {
|
||||
|
||||
+44
-38
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.dto.AbstractLeaderboardDTO;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPerspectiveLifecycle;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPerspectiveOwnSettings;
|
||||
@@ -40,12 +41,13 @@ import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class LeaderboardEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
public static final long DEFAULT_REFRESH_INTERVAL_MILLIS = 3000l;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(LeaderboardEntryPoint.class.getName());
|
||||
|
||||
private StringMessages stringmessages = StringMessages.INSTANCE;
|
||||
private UUID eventId;
|
||||
private String leaderboardName;
|
||||
private String leaderboardGroupName;
|
||||
private AbstractLeaderboardDTO leaderboardDTO;
|
||||
@@ -58,7 +60,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
leaderboardContextDefinition = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new LeaderboardContextDefinition());
|
||||
|
||||
final UUID eventId = leaderboardContextDefinition.getEventId();
|
||||
eventId = leaderboardContextDefinition.getEventId();
|
||||
|
||||
leaderboardName = leaderboardContextDefinition.getLeaderboardName();
|
||||
leaderboardGroupName = leaderboardContextDefinition.getLeaderboardGroupName();
|
||||
@@ -67,9 +69,8 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
if (eventId == null) {
|
||||
checkLeaderboardNameAndCreateUI(); // use null-initialized event field
|
||||
} else {
|
||||
// TODO it seems we do not really need the EventDTO. What's the intention of loading it? Should we
|
||||
// visualize some information in the header?
|
||||
sailingService.getEventById(eventId, /* withStatisticalData */false,
|
||||
// TODO it seems we do not really need the EventDTO. What's the intention of loading it? Should we visualize some information in the header?
|
||||
getSailingService().getEventById(eventId, /* withStatisticalData */false,
|
||||
new MarkedAsyncCallback<EventDTO>(new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -78,7 +79,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
@Override
|
||||
public void onSuccess(EventDTO result) {
|
||||
if (result != null) {
|
||||
if(result != null) {
|
||||
leaderboardDTO = result.getLeaderboardByName(leaderboardName);
|
||||
}
|
||||
checkLeaderboardNameAndCreateUI();
|
||||
@@ -89,27 +90,27 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkLeaderboardNameAndCreateUI() {
|
||||
if (leaderboardDTO == null) {
|
||||
sailingService.getLeaderboard(leaderboardName,
|
||||
new MarkedAsyncCallback<StrippedLeaderboardDTO>(new AsyncCallback<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public void onSuccess(StrippedLeaderboardDTO leaderboardDTO) {
|
||||
if (leaderboardDTO != null) {
|
||||
LeaderboardEntryPoint.this.leaderboardDTO = leaderboardDTO;
|
||||
Window.setTitle(leaderboardName);
|
||||
loadSettingsAndCreateUI();
|
||||
} else {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
if(leaderboardDTO == null) {
|
||||
getSailingService().getLeaderboard(leaderboardName,
|
||||
new MarkedAsyncCallback<StrippedLeaderboardDTO>(new AsyncCallback<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public void onSuccess(StrippedLeaderboardDTO leaderboardDTO) {
|
||||
if (leaderboardDTO != null) {
|
||||
LeaderboardEntryPoint.this.leaderboardDTO = leaderboardDTO;
|
||||
Window.setTitle(leaderboardName);
|
||||
loadSettingsAndCreateUI();
|
||||
} else {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: " + t.getMessage());
|
||||
}
|
||||
}));
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: " + t.getMessage());
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
loadSettingsAndCreateUI();
|
||||
}
|
||||
@@ -118,13 +119,13 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
private void loadSettingsAndCreateUI() {
|
||||
long delayBetweenAutoAdvancesInMilliseconds = DEFAULT_REFRESH_INTERVAL_MILLIS;
|
||||
final Timer timer = new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds);
|
||||
|
||||
|
||||
// make a single live request as the default but don't continue to play by default
|
||||
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory
|
||||
.createStoredSettingsLocatorForLeaderboard(leaderboardContextDefinition);
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
.createStoredSettingsLocatorForLeaderboard(leaderboardContextDefinition);
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
logger.log(Level.SEVERE, "Could not load detailtypes", caught);
|
||||
@@ -147,7 +148,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
final MetaLeaderboardViewer leaderboardViewer = new MetaLeaderboardViewer(
|
||||
null, context, rootComponentLifeCycle, defaultSettings,
|
||||
sailingService, new AsyncActionsExecutor(), timer, null,
|
||||
getSailingService(), new AsyncActionsExecutor(), timer, null,
|
||||
leaderboardGroupName, leaderboardName, LeaderboardEntryPoint.this,
|
||||
getStringMessages(), getActualChartDetailType(defaultSettings),
|
||||
result);
|
||||
@@ -174,8 +175,8 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
@Override
|
||||
public void onSuccess(
|
||||
PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings> defaultSettings) {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -189,7 +190,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
configureWithSettings(defaultSettings, timer);
|
||||
final MultiRaceLeaderboardViewer leaderboardViewer = new MultiRaceLeaderboardViewer(
|
||||
null, context, rootComponentLifeCycle,
|
||||
defaultSettings, sailingService,
|
||||
defaultSettings, getSailingService(),
|
||||
new AsyncActionsExecutor(), timer,
|
||||
leaderboardGroupName, leaderboardName,
|
||||
LeaderboardEntryPoint.this, getStringMessages(),
|
||||
@@ -212,25 +213,26 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private DetailType getActualChartDetailType(
|
||||
PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings> settings) {
|
||||
MultiCompetitorLeaderboardChartSettings chartSettings = settings
|
||||
.findSettingsByComponentId(MultiCompetitorLeaderboardChartLifecycle.ID);
|
||||
DetailType chartDetailType = chartSettings == null ? null : chartSettings.getDetailType();
|
||||
|
||||
|
||||
if (chartDetailType == DetailType.REGATTA_NET_POINTS_SUM) {
|
||||
return chartDetailType;
|
||||
}
|
||||
return MultiCompetitorLeaderboardChartSettings.getDefaultDetailType(leaderboardDTO.type.isMetaLeaderboard());
|
||||
}
|
||||
|
||||
|
||||
private void createUi(Widget leaderboardViewer,
|
||||
PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings> settings, Timer timer,
|
||||
LeaderboardContextDefinition leaderboardContextSettings) {
|
||||
LeaderboardPerspectiveOwnSettings ownSettings = settings.getPerspectiveOwnSettings();
|
||||
|
||||
|
||||
DockLayoutPanel mainPanel = new DockLayoutPanel(Unit.PX);
|
||||
RootLayoutPanel.get().add(mainPanel);
|
||||
if (!ownSettings.isEmbedded()) {
|
||||
@@ -258,11 +260,15 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
+ ");-o-transform-origin: 0 0;-webkit-transform: scale(" + zoomTo
|
||||
+ ");-webkit-transform-origin: 0 0;");
|
||||
}
|
||||
|
||||
|
||||
if (perspectiveOwnSettings.isLifePlay()) {
|
||||
timer.setPlayMode(PlayModes.Live); // the leaderboard, viewed via the entry point, goes "live" and "playing"
|
||||
// if an auto-refresh
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderboardName;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -777,7 +777,7 @@ public abstract class LeaderboardPanel<LS extends LeaderboardSettings> extends A
|
||||
|
||||
protected abstract void setDefaultRaceColumnSelection(LS settings);
|
||||
|
||||
private void setValuesWithReferenceOrder(Iterable<DetailType> valuesToSet, List<DetailType> referenceOrder,
|
||||
private void setValuesWithReferenceOrder(Iterable<DetailType> valuesToSet, Collection<DetailType> referenceOrder,
|
||||
List<DetailType> collectionToSetValuesTo) {
|
||||
collectionToSetValuesTo.clear();
|
||||
collectionToSetValuesTo.addAll(referenceOrder);
|
||||
|
||||
+14
-7
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.common.security.Permission;
|
||||
import com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboardedit.LeaderboardEditContextDefinition;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint;
|
||||
@@ -29,22 +30,23 @@ import com.sap.sse.security.ui.authentication.generic.GenericAuthentication;
|
||||
import com.sap.sse.security.ui.authentication.generic.GenericAuthorizedContentDecorator;
|
||||
import com.sap.sse.security.ui.authentication.generic.sapheader.SAPHeaderWithAuthentication;
|
||||
|
||||
public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
public class LeaderboardEditPage extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
private static final Logger logger = Logger.getLogger(LeaderboardEntryPoint.class.getName());
|
||||
private String leaderboardName;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
|
||||
sailingService.getLeaderboardNames(new MarkedAsyncCallback<List<String>>(
|
||||
final LeaderboardEditContextDefinition settings = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new LeaderboardEditContextDefinition());
|
||||
leaderboardName = settings.getLeaderboardName();
|
||||
getSailingService().getLeaderboardNames(new MarkedAsyncCallback<List<String>>(
|
||||
new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onSuccess(List<String> leaderboardNames) {
|
||||
final LeaderboardEditContextDefinition settings = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new LeaderboardEditContextDefinition());
|
||||
final String leaderboardName = settings.getLeaderboardName();
|
||||
if (leaderboardNames.contains(leaderboardName)) {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName, new AsyncCallback<Iterable<DetailType>>() {
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName, null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -60,7 +62,7 @@ public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
authorizedContentDecorator.setContentWidgetFactory(new WidgetFactory() {
|
||||
@Override
|
||||
public Widget get() {
|
||||
EditableLeaderboardPanel leaderboardPanel = new EditableLeaderboardPanel(sailingService, new AsyncActionsExecutor(), leaderboardName, null,
|
||||
EditableLeaderboardPanel leaderboardPanel = new EditableLeaderboardPanel(getSailingService(), new AsyncActionsExecutor(), leaderboardName, null,
|
||||
LeaderboardEditPage.this, getStringMessages(), userAgent, result);
|
||||
leaderboardPanel.ensureDebugId("EditableLeaderboardPanel");
|
||||
return leaderboardPanel;
|
||||
@@ -91,4 +93,9 @@ public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
header.getElement().getStyle().setWidth(100, Unit.PCT);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderboardName;
|
||||
}
|
||||
}
|
||||
+13
-6
@@ -18,6 +18,7 @@ import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.dto.PairingListDTO;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.ui.adminconsole.PairingListPreviewDialog;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -25,19 +26,21 @@ import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
|
||||
public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class PairingListEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
|
||||
private PairingListContextDefinition pairingListContextDefinition;
|
||||
|
||||
private StringMessages stringMessages = StringMessages.INSTANCE;
|
||||
private StrippedLeaderboardDTO strippedLeaderboardDTO;
|
||||
|
||||
private String leaderboardName;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
pairingListContextDefinition = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new PairingListContextDefinition());
|
||||
this.sailingService.getLeaderboard(pairingListContextDefinition.getLeaderboardName(),
|
||||
leaderboardName = pairingListContextDefinition.getLeaderboardName();
|
||||
getSailingService().getLeaderboard(leaderboardName,
|
||||
new AsyncCallback<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -68,12 +71,12 @@ public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
contentPanel.getElement().getStyle().setProperty("marginTop", "15px");
|
||||
contentPanel.getElement().getStyle().setProperty("marginBottom", "15px");
|
||||
scrollPanel.add(contentPanel);
|
||||
sailingService.getPairingListFromRaceLogs(pairingListContextDefinition.getLeaderboardName(),
|
||||
getSailingService().getPairingListFromRaceLogs(pairingListContextDefinition.getLeaderboardName(),
|
||||
new AsyncCallback<PairingListDTO>() {
|
||||
@Override
|
||||
public void onSuccess(PairingListDTO result) {
|
||||
if (strippedLeaderboardDTO != null) {
|
||||
sailingService.getRaceDisplayNamesFromLeaderboard(strippedLeaderboardDTO.getName(),
|
||||
getSailingService().getRaceDisplayNamesFromLeaderboard(strippedLeaderboardDTO.getName(),
|
||||
result.getRaceColumnNames(), new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -126,7 +129,7 @@ public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
pairingListPanel.getElement().getStyle().setProperty("marginTop", "15px");
|
||||
return pairingListPanel;
|
||||
}
|
||||
|
||||
|
||||
private native void printPairingListGrid(String pageHTMLContent) /*-{
|
||||
var frameID = '__gwt_historyFrame';
|
||||
var frame = $doc.getElementById(frameID);
|
||||
@@ -167,4 +170,8 @@ public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
}, 100);
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderboardName;
|
||||
}
|
||||
}
|
||||
+12
-6
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.common.dto.BoatDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceBoardPerspectiveOwnSettings;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProvider;
|
||||
@@ -62,7 +63,7 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.authentication.generic.sapheader.SAPHeaderWithAuthentication;
|
||||
|
||||
public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
private static final String PARAM_REGATTA_LIKE_NAME = "regattaLikeName";
|
||||
private static final String PARAM_RACE_COLUMN_NAME = "raceColumnName";
|
||||
private static final String PARAM_FLEET_NAME = "fleetName";
|
||||
@@ -122,13 +123,13 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
defaultRaceMapSettings.isShowDouglasPeuckerPoints(), true,
|
||||
defaultRaceMapSettings.getStartCountDownFontSizeScaling());
|
||||
|
||||
sailingService.getRaceIdentifier(regattaLikeName, raceColumnName, fleetName, new AsyncCallback<RegattaAndRaceIdentifier>() {
|
||||
getSailingService().getRaceIdentifier(regattaLikeName, raceColumnName, fleetName, new AsyncCallback<RegattaAndRaceIdentifier>() {
|
||||
@Override
|
||||
public void onSuccess(final RegattaAndRaceIdentifier selectedRaceIdentifier) {
|
||||
if (selectedRaceIdentifier == null) {
|
||||
createErrorPage(getStringMessages().couldNotObtainRace(regattaLikeName, raceColumnName, fleetName, /* technicalErrorMessage */ ""));
|
||||
} else {
|
||||
sailingService.getCompetitorBoats(selectedRaceIdentifier, new AsyncCallback<Map<CompetitorDTO, BoatDTO>>() {
|
||||
getSailingService().getCompetitorBoats(selectedRaceIdentifier, new AsyncCallback<Map<CompetitorDTO, BoatDTO>>() {
|
||||
@Override
|
||||
public void onSuccess(Map<CompetitorDTO, BoatDTO> result) {
|
||||
createEmbeddedMap(selectedRaceIdentifier, result, raceboardPerspectiveSettings, raceMapSettings,
|
||||
@@ -187,7 +188,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
return true;
|
||||
}
|
||||
};
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, asyncActionsExecutor, /* errorReporter */ this,
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(getSailingService(), asyncActionsExecutor, /* errorReporter */ this,
|
||||
Collections.singleton(selectedRaceIdentifier), 30000l /* requestInterval*/);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(new RaceTimesInfoProviderListener() {
|
||||
@Override
|
||||
@@ -208,7 +209,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
competitorSelection = createEmptyFilterCompetitorModel(colorProvider, competitorsAndBoats); // show no competitors
|
||||
}
|
||||
final RaceMap raceMap = new RaceMap(null, null, new RaceMapLifecycle(getStringMessages()), raceMapSettings,
|
||||
sailingService, asyncActionsExecutor, /* errorReporter */ EmbeddedMapAndWindChartEntryPoint.this, timer,
|
||||
getSailingService(), asyncActionsExecutor, /* errorReporter */ EmbeddedMapAndWindChartEntryPoint.this, timer,
|
||||
competitorSelection, new RaceCompetitorSet(competitorSelection), getStringMessages(), selectedRaceIdentifier,
|
||||
raceMapResources, /* showHeaderPanel */ false, new DefaultQuickRanksDTOProvider()) {
|
||||
@Override
|
||||
@@ -219,7 +220,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
};
|
||||
final WindChart windChart;
|
||||
if (raceboardPerspectiveSettings.isShowWindChart()) {
|
||||
windChart = new WindChart(null, null, new WindChartLifecycle(getStringMessages()), sailingService,
|
||||
windChart = new WindChart(null, null, new WindChartLifecycle(getStringMessages()), getSailingService(),
|
||||
selectedRaceIdentifier, timer,
|
||||
timeRangeWithZoomProvider, new WindChartSettings(), getStringMessages(),
|
||||
asyncActionsExecutor, /* errorReporter */
|
||||
@@ -254,4 +255,9 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
p.insert(raceMap.getEntryWidget(), raceMap, Direction.CENTER, 400);
|
||||
p.addStyleName("dockLayoutPanel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaLikeName;
|
||||
}
|
||||
}
|
||||
+27
-13
@@ -14,6 +14,7 @@ import com.google.gwt.user.client.ui.RootLayoutPanel;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceBoardPerspectiveOwnSettings;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
|
||||
@@ -38,7 +39,7 @@ import com.sap.sse.security.ui.authentication.generic.sapheader.SAPHeaderWithAut
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class RaceBoardEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
private RaceWithCompetitorsAndBoatsDTO selectedRace;
|
||||
|
||||
/**
|
||||
@@ -48,10 +49,13 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
private RaceboardContextDefinition raceboardContextDefinition;
|
||||
|
||||
private String leaderBoardName;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) mediaService, RemoteServiceMappingConstants.mediaServiceRemotePath);
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) mediaService,
|
||||
RemoteServiceMappingConstants.mediaServiceRemotePath);
|
||||
raceboardContextDefinition = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new RaceboardContextDefinition());
|
||||
final RaceBoardModes finalMode;
|
||||
@@ -61,12 +65,16 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
finalMode = null;
|
||||
}
|
||||
if (raceboardContextDefinition.getRegattaName() == null || raceboardContextDefinition.getRegattaName().isEmpty()
|
||||
|| raceboardContextDefinition.getRaceName() == null || raceboardContextDefinition.getRaceName().isEmpty()
|
||||
|| raceboardContextDefinition.getRaceName() == null
|
||||
|| raceboardContextDefinition.getRaceName().isEmpty()
|
||||
|| raceboardContextDefinition.getLeaderboardName() == null
|
||||
|| raceboardContextDefinition.getLeaderboardName().isEmpty()) {
|
||||
createErrorPage(getStringMessages().requiresRegattaRaceAndLeaderboard());
|
||||
return;
|
||||
}
|
||||
|
||||
leaderBoardName = raceboardContextDefinition.getLeaderboardName();
|
||||
|
||||
AsyncCallback<RaceboardDataDTO> asyncCallback = new AsyncCallback<RaceboardDataDTO>() {
|
||||
@Override
|
||||
public void onSuccess(RaceboardDataDTO raceboardData) {
|
||||
@@ -93,17 +101,18 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
}
|
||||
if (raceboardData.getRace() == null) {
|
||||
createErrorPage(getStringMessages().couldNotFindRaceInRegatta(raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getRegattaName()));
|
||||
createErrorPage(getStringMessages().couldNotFindRaceInRegatta(
|
||||
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getRegattaName()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final boolean showChartMarkEditMediaButtonsAndVideo = !DeviceDetector.isMobile();
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory
|
||||
.createStoredSettingsLocatorForRaceBoard(raceboardContextDefinition,
|
||||
finalMode != null ? finalMode.name() : null);
|
||||
// TODO bug2822: also determine regatta's boat change parameter and parameterize Leaderboard settings
|
||||
// --> show boat info column yes/no?
|
||||
sailingService.determineDetailTypesForCompetitorChart(
|
||||
getSailingService().determineDetailTypesForCompetitorChart(
|
||||
raceboardContextDefinition.getLeaderboardGroupName(),
|
||||
raceboardData.getRace().getRaceIdentifier(), new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@@ -114,9 +123,9 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> chartAllowedTypes) {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(
|
||||
raceboardContextDefinition.getLeaderboardName(),
|
||||
new AsyncCallback<Iterable<DetailType>>() {
|
||||
raceboardData.getRace().getRaceIdentifier(), new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
reportError(
|
||||
@@ -152,13 +161,13 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
reportError("Error trying to create the raceboard: " + caught.getMessage());
|
||||
}
|
||||
};
|
||||
sailingService.getRaceboardData(raceboardContextDefinition.getRegattaName(),
|
||||
getSailingService().getRaceboardData(raceboardContextDefinition.getRegattaName(),
|
||||
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getLeaderboardName(),
|
||||
raceboardContextDefinition.getLeaderboardGroupName(), raceboardContextDefinition.getEventId(),
|
||||
asyncCallback);
|
||||
@@ -185,10 +194,10 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
selectedRace = raceboardData.getRace();
|
||||
Window.setTitle(selectedRace.getName());
|
||||
AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, asyncActionsExecutor, this,
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(getSailingService(), asyncActionsExecutor, this,
|
||||
Collections.singletonList(selectedRace.getRaceIdentifier()), 5000l /* requestInterval*/);
|
||||
RaceBoardPanel raceBoardPerspective = new RaceBoardPanel(parent, context, raceLifeCycle, settings,
|
||||
sailingService, mediaService, getUserService(), asyncActionsExecutor,
|
||||
getSailingService(), mediaService, getUserService(), asyncActionsExecutor,
|
||||
raceboardData.getCompetitorAndTheirBoats(), timer, selectedRace.getRaceIdentifier(),
|
||||
raceboardContextDefinition.getLeaderboardName(), raceboardContextDefinition.getLeaderboardGroupName(),
|
||||
raceboardContextDefinition.getEventId(), RaceBoardEntryPoint.this, getStringMessages(), userAgent,
|
||||
@@ -196,4 +205,9 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
RootLayoutPanel.get().add(raceBoardPerspective.getEntryWidget());
|
||||
return raceBoardPerspective;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderBoardName;
|
||||
}
|
||||
}
|
||||
+80
-18
@@ -53,6 +53,10 @@ import java.util.stream.StreamSupport;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
@@ -278,6 +282,7 @@ import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.security.Permission;
|
||||
import com.sap.sailing.domain.common.security.Permission.Mode;
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
@@ -306,10 +311,10 @@ import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
import com.sap.sailing.domain.racelog.RaceStateOfSameDayHelper;
|
||||
import com.sap.sailing.domain.racelog.impl.GPSFixStoreImpl;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
||||
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
|
||||
@@ -318,6 +323,7 @@ import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||
import com.sap.sailing.domain.sharding.ShardingContext;
|
||||
import com.sap.sailing.domain.swisstimingadapter.StartList;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapter;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapterFactory;
|
||||
@@ -522,8 +528,8 @@ import com.sap.sse.common.CountryCode;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.PairingListCreationException;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Timed;
|
||||
@@ -2539,6 +2545,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void checkLeaderboardRouting(String leaderboardName) {
|
||||
final String currentRequestUrl = getThreadLocalRequest().getRequestURL().toString();
|
||||
if (!currentRequestUrl.contains("/leaderboard/")) {
|
||||
logger.log(Level.WARNING, "Leaderboard routing stacktrace", new RuntimeException("Request without leaderboard routing information"));
|
||||
} else {
|
||||
if (currentRequestUrl.contains(leaderboardName)) {
|
||||
logger.info("leaderboard access matches leaderboard url");
|
||||
} else {
|
||||
logger.info("leaderboard access to " + leaderboardName + " does not match request url " + currentRequestUrl);
|
||||
logger.log(Level.SEVERE, "Leaderboard routing stacktrace", new RuntimeException("Request without leaderboard routing information"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link LeaderboardDTO} for <code>leaderboard</code> and fills in the name, race master data
|
||||
@@ -2549,6 +2569,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
* If <code>withGeoLocationData</code> is <code>true</code> the geographical location of all races will be determined.
|
||||
*/
|
||||
private StrippedLeaderboardDTO createStrippedLeaderboardDTO(Leaderboard leaderboard, boolean withGeoLocationData, boolean withStatisticalData) {
|
||||
checkLeaderboardRouting(leaderboard.getName());
|
||||
|
||||
StrippedLeaderboardDTO leaderboardDTO = new StrippedLeaderboardDTO(convertToBoatClassDTO(leaderboard.getBoatClass()));
|
||||
TimePoint startOfLatestRace = null;
|
||||
Long delayToLiveInMillisForLatestRace = null;
|
||||
@@ -5418,6 +5440,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
|
||||
dto.defaultRacingProcedureType = configuration.getDefaultRacingProcedureType();
|
||||
dto.defaultCourseDesignerMode = configuration.getDefaultCourseDesignerMode();
|
||||
dto.defaultProtestTimeDuration = configuration.getDefaultProtestTimeDuration();
|
||||
|
||||
if (configuration.getRRS26Configuration() != null) {
|
||||
dto.rrs26Configuration = new DeviceConfigurationDTO.RegattaConfigurationDTO.RRS26ConfigurationDTO();
|
||||
@@ -5475,6 +5498,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
RegattaConfigurationImpl configuration = new RegattaConfigurationImpl();
|
||||
configuration.setDefaultRacingProcedureType(dto.defaultRacingProcedureType);
|
||||
configuration.setDefaultCourseDesignerMode(dto.defaultCourseDesignerMode);
|
||||
configuration.setDefaultProtestTimeDuration(dto.defaultProtestTimeDuration);
|
||||
if (dto.rrs26Configuration != null) {
|
||||
RRS26ConfigurationImpl config = new RRS26ConfigurationImpl();
|
||||
applyGeneralRacingProcedureConfigProperties(dto.rrs26Configuration, config);
|
||||
@@ -5904,10 +5928,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
Util.addAll(competitorToBoatMappingsRegistered.keySet(), competitorsToUnregister);
|
||||
for (final Entry<CompetitorType, Boat> e : competitorToBoatMappingsRegistered.entrySet()) {
|
||||
CompetitorType competitor = e.getKey();
|
||||
if (competitorToBoatMappingsToRegister.get(competitor) == e.getValue()) {
|
||||
// User wants to map competitor to boat, and that mapping already exists; neither add nor remove this registration but leave as is:
|
||||
competitorToBoatMappingsToRegister.remove(competitor);
|
||||
competitorsToUnregister.remove(competitor);
|
||||
if (competitorToBoatMappingsToRegister.containsKey(competitor)) { // is competitor to be registered?
|
||||
final Boat boatOfCompetitorToRegister = competitorToBoatMappingsToRegister.get(competitor);
|
||||
final Boat boatOfRegisteredCompetitor = e.getValue();
|
||||
if (boatOfCompetitorToRegister == boatOfRegisteredCompetitor) {
|
||||
// User wants to map competitor to boat, and that mapping already exists; neither add nor remove this registration but leave as is:
|
||||
competitorToBoatMappingsToRegister.remove(competitor);
|
||||
competitorsToUnregister.remove(competitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return competitorsToUnregister;
|
||||
@@ -6989,7 +7017,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
return new MarkTracksDTO(markTracks);
|
||||
}
|
||||
|
||||
private MarkTrackDTO getMarkTrack(Leaderboard leaderboard, RaceColumn raceColumn, Fleet fleet, String markIdAsString) {
|
||||
private MarkTrackDTO getMarkTrack(Leaderboard leaderboard, RaceColumn raceColumn, Fleet fleet,
|
||||
String markIdAsString) {
|
||||
MarkDTO markDTO = null;
|
||||
Mark mark = null;
|
||||
for (final Mark currMark : raceColumn.getAvailableMarks(fleet)) {
|
||||
@@ -6999,25 +7028,39 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (markDTO != null) {
|
||||
final TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
final GPSFixTrack<Mark, ? extends GPSFix> markTrack;
|
||||
if (trackedRace != null) {
|
||||
markTrack = trackedRace.getOrCreateTrack(mark);
|
||||
} else {
|
||||
DynamicGPSFixTrackImpl<Mark> writeableMarkTrack = new DynamicGPSFixTrackImpl<Mark>(mark, BoatClass.APPROXIMATE_AVERAGE_MANEUVER_DURATION.asMillis());
|
||||
DynamicGPSFixTrackImpl<Mark> writeableMarkTrack = new DynamicGPSFixTrackImpl<Mark>(mark,
|
||||
BoatClass.APPROXIMATE_AVERAGE_MANEUVER_DURATION.asMillis());
|
||||
markTrack = writeableMarkTrack;
|
||||
final RaceLog raceLog = raceColumn.getRaceLog(fleet);
|
||||
final RegattaLog regattaLog = raceColumn.getRegattaLog();
|
||||
final TrackingTimesFinder trackingTimesFinder = new TrackingTimesFinder(raceLog);
|
||||
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = trackingTimesFinder.analyze();
|
||||
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = trackingTimesFinder
|
||||
.analyze();
|
||||
try {
|
||||
GPSFixStore gfs = new GPSFixStoreImpl(getService().getSensorFixStore());
|
||||
gfs.loadMarkTrack(writeableMarkTrack, regattaLog, mark,
|
||||
trackingTimes.getA().getTimePoint(), trackingTimes.getB().getTimePoint());
|
||||
SensorFixStore sensorFixStore = getService().getSensorFixStore();
|
||||
List<DeviceMappingWithRegattaLogEvent<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(
|
||||
regattaLog).analyze().get(mark);
|
||||
if (mappings != null) {
|
||||
for (DeviceMapping<Mark> mapping : mappings) {
|
||||
final TimePoint from = Util.getLatestOfTimePoints(trackingTimes.getA().getTimePoint(),
|
||||
mapping.getTimeRange().from());
|
||||
final TimePoint to = Util.getEarliestOfTimePoints(trackingTimes.getB().getTimePoint(),
|
||||
mapping.getTimeRange().to());
|
||||
sensorFixStore.<GPSFix> loadFixes(loadedFix -> writeableMarkTrack.add(loadedFix, true),
|
||||
mapping.getDevice(), from, to, false, () -> false, progressIgnoringConsumer -> {
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.info("Error trying to load mark track for mark "+mark+" from "+trackingTimes.getA()+" to "+trackingTimes.getB());
|
||||
logger.info("Error trying to load mark track for mark " + mark + " from " + trackingTimes.getA()
|
||||
+ " to " + trackingTimes.getB());
|
||||
}
|
||||
}
|
||||
Iterable<GPSFixDTO> gpsFixDTOTrack = convertToGPSFixDTOTrack(markTrack);
|
||||
@@ -7429,7 +7472,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<DetailType> getAvailableDetailTypesForLeaderboard(String leaderboardName) {
|
||||
public Iterable<DetailType> getAvailableDetailTypesForLeaderboard(String leaderboardName, RegattaAndRaceIdentifier raceIdentifierOrNull) {
|
||||
final Set<DetailType> allowed = new HashSet<>();
|
||||
allowed.addAll(DetailType.getAllNonRestrictedDetailTypes());
|
||||
final Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
@@ -7438,7 +7481,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
boolean hasExtendedBravoFixes = false;
|
||||
abort: for (RaceColumn race : leaderboard.getRaceColumns()) {
|
||||
for (Fleet fleet : race.getFleets()) {
|
||||
TrackedRace trace = race.getTrackedRace(fleet);
|
||||
if (raceIdentifierOrNull != null && !raceIdentifierOrNull.equals(race.getRaceIdentifier(fleet))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final TrackedRace trace = race.getTrackedRace(fleet);
|
||||
if (trace != null) {
|
||||
final DynamicTrackedRace trackedRace = getService().getTrackedRace(trace.getRaceIdentifier());
|
||||
if (trackedRace != null) {
|
||||
@@ -7815,7 +7862,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean checkIfRaceIsTracked(RegattaAndRaceIdentifier race) {
|
||||
public Boolean checkIfRaceIsTracking(RegattaAndRaceIdentifier race) {
|
||||
boolean result = false;
|
||||
DynamicTrackedRace trace = getService().getTrackedRace(race);
|
||||
if (trace != null) {
|
||||
@@ -7826,4 +7873,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
||||
ShardingType identifiedShardingType = null;
|
||||
try {
|
||||
if (req instanceof HttpServletRequest) {
|
||||
identifiedShardingType = ShardingContext.identifyAndSetShardingConstraint(((HttpServletRequest) req).getPathInfo());
|
||||
}
|
||||
super.service(req, res);
|
||||
} finally {
|
||||
if (identifiedShardingType != null) {
|
||||
ShardingContext.clearShardingConstraint(identifiedShardingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -6,6 +6,7 @@ import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.CourseDesignerMode;
|
||||
import com.sap.sailing.domain.common.racelog.Flags;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
public class DeviceConfigurationDTO implements IsSerializable {
|
||||
|
||||
@@ -40,6 +41,7 @@ public class DeviceConfigurationDTO implements IsSerializable {
|
||||
}
|
||||
public RacingProcedureType defaultRacingProcedureType;
|
||||
public CourseDesignerMode defaultCourseDesignerMode;
|
||||
public Duration defaultProtestTimeDuration;
|
||||
|
||||
public RRS26ConfigurationDTO rrs26Configuration;
|
||||
public SWCStartConfigurationDTO swcStartConfiguration;
|
||||
|
||||
+3
-3
@@ -38,7 +38,7 @@ public class SpectatorEntryPoint extends AbstractSailingEntryPoint implements Re
|
||||
} else {
|
||||
groupName = groupParamValue;
|
||||
Window.setTitle(groupName);
|
||||
sailingService.getLeaderboardGroupByName(groupName, false /*withGeoLocationData*/, new AsyncCallback<LeaderboardGroupDTO>() {
|
||||
getSailingService().getLeaderboardGroupByName(groupName, false /*withGeoLocationData*/, new AsyncCallback<LeaderboardGroupDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError(getStringMessages().noLeaderboardGroupWithNameFound(groupName));
|
||||
@@ -58,11 +58,11 @@ public class SpectatorEntryPoint extends AbstractSailingEntryPoint implements Re
|
||||
// DON'T DELETE -> the EventOverviewPanel will replace the LeaderboardGroupOverviewPanel later on
|
||||
// EventOverviewPanel eventOverviewPanel = new EventOverviewPanel(sailingService, this, stringMessages, showRaceDetails);
|
||||
// groupOverviewPanel.add( eventOverviewPanel);
|
||||
LeaderboardGroupOverviewPanel leaderboardGroupOverviewPanel = new LeaderboardGroupOverviewPanel(sailingService, this, getStringMessages(), settings.isShowRaceDetails());
|
||||
LeaderboardGroupOverviewPanel leaderboardGroupOverviewPanel = new LeaderboardGroupOverviewPanel(getSailingService(), this, getStringMessages(), settings.isShowRaceDetails());
|
||||
groupOverviewPanel.add(leaderboardGroupOverviewPanel);
|
||||
rootPanel.add(groupOverviewPanel);
|
||||
} else {
|
||||
LeaderboardGroupPanel groupPanel = new LeaderboardGroupPanel(sailingService, getStringMessages(), this,
|
||||
LeaderboardGroupPanel groupPanel = new LeaderboardGroupPanel(getSailingService(), getStringMessages(), this,
|
||||
groupName, settings.getViewMode(), embedded, settings.isShowRaceDetails(), settings.isCanReplayDuringLiveRaces(),
|
||||
settings.isShowMapControls());
|
||||
groupAndFeedbackPanel.add(groupPanel);
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
-106
@@ -1,106 +0,0 @@
|
||||
package com.sap.sailing.mongodb.test;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoException;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.PersistenceFactory;
|
||||
import com.sap.sailing.domain.persistence.impl.CollectionNames;
|
||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoSensorFixStoreImpl;
|
||||
import com.sap.sailing.domain.racelog.impl.GPSFixStoreImpl;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
|
||||
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class StoreGPSFixTrackTest extends AbstractMongoDBTest {
|
||||
public StoreGPSFixTrackTest() throws UnknownHostException, MongoException {
|
||||
super();
|
||||
}
|
||||
|
||||
@After
|
||||
public void dropCollection() {
|
||||
DB db = getMongoService().getDB();
|
||||
db.getCollection(CollectionNames.GPS_FIXES.name()).drop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndLoadFixes() throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||
TypeBasedServiceFinderFactory factory = new MockSmartphoneImeiServiceFinderFactory();
|
||||
AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
|
||||
Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", "c", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
|
||||
MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService(), factory);
|
||||
DomainObjectFactory domainObjectFactory = PersistenceFactory.INSTANCE.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE, factory);
|
||||
GPSFixStore store = new GPSFixStoreImpl(new MongoSensorFixStoreImpl(mongoObjectFactory, domainObjectFactory, factory));
|
||||
|
||||
TimePoint time0 = new MillisecondsTimePoint(0);
|
||||
TimePoint time1 = new MillisecondsTimePoint(1);
|
||||
TimePoint time2 = new MillisecondsTimePoint(2);
|
||||
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(30, 40), time0,
|
||||
new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(30, 40), time1,
|
||||
new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0)));
|
||||
//lies outside of mapping range
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(30, 40), time2,
|
||||
new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0)));
|
||||
DeviceIdentifier device1 = new SmartphoneImeiIdentifier("a");
|
||||
store.storeFix(device1, fix1);
|
||||
store.storeFix(device1, fix2);
|
||||
store.storeFix(device1, fix3);
|
||||
|
||||
GPSFix fix4 = new GPSFixImpl(new DegreePosition(40, 50), time0);
|
||||
DeviceIdentifier device2 = new SmartphoneImeiIdentifier("b");
|
||||
store.storeFix(device2, fix4);
|
||||
|
||||
RegattaLog regattaLog = new RegattaLogImpl("racelog");
|
||||
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(time0, author, comp, device1, time0, time1));
|
||||
regattaLog.add(new RegattaLogDeviceMarkMappingEventImpl(time0, author, mark, device2, time0, time1));
|
||||
|
||||
DynamicGPSFixMovingTrackImpl<Competitor> track1 = new DynamicGPSFixMovingTrackImpl<>(comp, 0);
|
||||
store.loadCompetitorTrack(track1, regattaLog, comp);
|
||||
DynamicGPSFixTrackImpl<Mark> track2 = new DynamicGPSFixTrackImpl<>(mark, 0);
|
||||
store.loadMarkTrack(track2, regattaLog, mark);
|
||||
track1.lockForRead();
|
||||
assertEquals(2, Util.size(track1.getRawFixes()));
|
||||
assertTrue(track1.getFirstRawFix() instanceof GPSFixMoving);
|
||||
track1.unlockAfterRead();
|
||||
track2.lockForRead();
|
||||
assertEquals(1, Util.size(track2.getRawFixes()));
|
||||
track2.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
+18
-10
@@ -15,9 +15,10 @@ import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.RegattaConfigurationJsonSerializer;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
|
||||
public class RegattaConfigurationJsonDeserializer implements JsonDeserializer<RegattaConfiguration> {
|
||||
|
||||
|
||||
public static RegattaConfigurationJsonDeserializer create() {
|
||||
return new RegattaConfigurationJsonDeserializer(RRS26ConfigurationJsonDeserializer.create(), SWCStartConfigurationJsonDeserializer.create(),
|
||||
GateStartConfigurationJsonDeserializer.create(), ESSConfigurationJsonDeserializer.create(),
|
||||
@@ -30,8 +31,8 @@ public class RegattaConfigurationJsonDeserializer implements JsonDeserializer<Re
|
||||
private final ESSConfigurationJsonDeserializer essDeserializer;
|
||||
private final RacingProcedureConfigurationJsonDeserializer basicDeserializer;
|
||||
private final LeagueConfigurationJsonDeserializer leagueDeserializer;
|
||||
|
||||
public RegattaConfigurationJsonDeserializer(RRS26ConfigurationJsonDeserializer rrs26, SWCStartConfigurationJsonDeserializer swcStart,
|
||||
|
||||
public RegattaConfigurationJsonDeserializer(RRS26ConfigurationJsonDeserializer rrs26, SWCStartConfigurationJsonDeserializer swcStart,
|
||||
GateStartConfigurationJsonDeserializer gateStart, ESSConfigurationJsonDeserializer ess,
|
||||
RacingProcedureConfigurationJsonDeserializer basicDeserializer, LeagueConfigurationJsonDeserializer leagueDeserializer) {
|
||||
this.rrs26Deserializer = rrs26;
|
||||
@@ -41,7 +42,7 @@ public class RegattaConfigurationJsonDeserializer implements JsonDeserializer<Re
|
||||
this.basicDeserializer = basicDeserializer;
|
||||
this.leagueDeserializer = leagueDeserializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RegattaConfiguration deserialize(JSONObject object) throws JsonDeserializationException {
|
||||
RegattaConfigurationImpl configuration = createConfiguration();
|
||||
@@ -57,7 +58,14 @@ public class RegattaConfigurationJsonDeserializer implements JsonDeserializer<Re
|
||||
RegattaConfigurationJsonSerializer.FIELD_DEFAULT_COURSE_DESIGNER_MODE).toString());
|
||||
configuration.setDefaultCourseDesignerMode(mode);
|
||||
}
|
||||
|
||||
|
||||
if (object.containsKey(RegattaConfigurationJsonSerializer.FIELD_DEFAULT_PROTEST_TIME_DURATION_MILLIS)) {
|
||||
final Number defaultProtestTimeDurationInMillis = (Number) object.get(
|
||||
RegattaConfigurationJsonSerializer.FIELD_DEFAULT_PROTEST_TIME_DURATION_MILLIS);
|
||||
configuration.setDefaultProtestTimeDuration(defaultProtestTimeDurationInMillis == null ? null :
|
||||
new MillisecondsDurationImpl(defaultProtestTimeDurationInMillis.longValue()));
|
||||
}
|
||||
|
||||
if (object.containsKey(RegattaConfigurationJsonSerializer.FIELD_RRS26)) {
|
||||
RRS26Configuration rrs26Configuration = rrs26Deserializer.deserialize(
|
||||
Helpers.getNestedObjectSafe(object, RegattaConfigurationJsonSerializer.FIELD_RRS26));
|
||||
@@ -71,18 +79,18 @@ public class RegattaConfigurationJsonDeserializer implements JsonDeserializer<Re
|
||||
}
|
||||
|
||||
if (object.containsKey(RegattaConfigurationJsonSerializer.FIELD_GATE_START)) {
|
||||
GateStartConfiguration gateStartConfiguration =
|
||||
GateStartConfiguration gateStartConfiguration =
|
||||
gateStartDeserializer.deserialize(
|
||||
Helpers.getNestedObjectSafe(object, RegattaConfigurationJsonSerializer.FIELD_GATE_START));
|
||||
configuration.setGateStartConfiguration(gateStartConfiguration);
|
||||
}
|
||||
|
||||
|
||||
if (object.containsKey(RegattaConfigurationJsonSerializer.FIELD_ESS)) {
|
||||
ESSConfiguration essConfiguration = essDeserializer.deserialize(
|
||||
Helpers.getNestedObjectSafe(object, RegattaConfigurationJsonSerializer.FIELD_ESS));
|
||||
configuration.setESSConfiguration(essConfiguration);
|
||||
}
|
||||
|
||||
|
||||
if (object.containsKey(RegattaConfigurationJsonSerializer.FIELD_BASIC)) {
|
||||
RacingProcedureConfiguration basicConfiguration = basicDeserializer.deserialize(
|
||||
Helpers.getNestedObjectSafe(object, RegattaConfigurationJsonSerializer.FIELD_BASIC));
|
||||
@@ -94,10 +102,10 @@ public class RegattaConfigurationJsonDeserializer implements JsonDeserializer<Re
|
||||
Helpers.getNestedObjectSafe(object, RegattaConfigurationJsonSerializer.FIELD_LEAGUE));
|
||||
configuration.setLeagueConfiguration(leagueConfiguration);
|
||||
}
|
||||
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
|
||||
protected RegattaConfigurationImpl createConfiguration() {
|
||||
return new RegattaConfigurationImpl();
|
||||
}
|
||||
|
||||
+10
-3
@@ -14,15 +14,16 @@ public class RegattaConfigurationJsonSerializer implements JsonSerializer<Regatt
|
||||
RacingProcedureConfigurationJsonSerializer.create(), LeagueConfigurationJsonSerializer.create());
|
||||
}
|
||||
|
||||
public static final Object FIELD_DEFAULT_RACING_PROCEDURE_TYPE = "defaultRacingProcedureType";
|
||||
public static final Object FIELD_DEFAULT_COURSE_DESIGNER_MODE = "defaultCourseDesignerMode";
|
||||
public static final String FIELD_DEFAULT_RACING_PROCEDURE_TYPE = "defaultRacingProcedureType";
|
||||
public static final String FIELD_DEFAULT_COURSE_DESIGNER_MODE = "defaultCourseDesignerMode";
|
||||
public static final String FIELD_DEFAULT_PROTEST_TIME_DURATION_MILLIS = "defaultProtestTimeDurationMillis";
|
||||
public static final String FIELD_RRS26 = "rrs26";
|
||||
public static final String FIELD_SWC_START = "swcStart";
|
||||
public static final String FIELD_GATE_START = "gateStart";
|
||||
public static final String FIELD_ESS = "ess";
|
||||
public static final String FIELD_LEAGUE = "league";
|
||||
public static final String FIELD_BASIC = "basic";
|
||||
|
||||
|
||||
private final JsonSerializer<RacingProcedureConfiguration> rrs26Serializer;
|
||||
private final JsonSerializer<RacingProcedureConfiguration> swcStartSerializer;
|
||||
private final JsonSerializer<RacingProcedureConfiguration> gateStartSerializer;
|
||||
@@ -47,9 +48,15 @@ public class RegattaConfigurationJsonSerializer implements JsonSerializer<Regatt
|
||||
if (object.getDefaultRacingProcedureType() != null) {
|
||||
result.put(FIELD_DEFAULT_RACING_PROCEDURE_TYPE, object.getDefaultRacingProcedureType().name());
|
||||
}
|
||||
|
||||
if (object.getDefaultCourseDesignerMode() != null) {
|
||||
result.put(FIELD_DEFAULT_COURSE_DESIGNER_MODE, object.getDefaultCourseDesignerMode().name());
|
||||
}
|
||||
|
||||
if (object.getDefaultProtestTimeDuration() != null) {
|
||||
result.put(FIELD_DEFAULT_PROTEST_TIME_DURATION_MILLIS, object.getDefaultProtestTimeDuration().asMillis());
|
||||
}
|
||||
|
||||
if (object.getRRS26Configuration() != null) {
|
||||
result.put(FIELD_RRS26, rrs26Serializer.serialize(object.getRRS26Configuration()));
|
||||
}
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.persistence.MongoWindStoreFactory;
|
||||
import com.sap.sailing.domain.persistence.PersistenceFactory;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||
import com.sap.sailing.domain.test.PositionAssert;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||
@@ -58,13 +58,13 @@ import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp.ReplicationServiceTestImpl;
|
||||
|
||||
/**
|
||||
* Runs the same tests as {@link TrackedRaceContentsReplicationTest}, but with a non-empty {@link GPSFixStore} that
|
||||
* Runs the same tests as {@link TrackedRaceContentsReplicationTest}, but with a non-empty {@link SensorFixStore} that
|
||||
* has special serialization requirements.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class TrackedRaceWithGPSFixStoreContentsReplicationTest extends AbstractServerReplicationTest {
|
||||
public class TrackedRaceWithSensorFixStoreContentsReplicationTest extends AbstractServerReplicationTest {
|
||||
private Competitor competitor;
|
||||
private DynamicTrackedRace trackedRace;
|
||||
private RegattaNameAndRaceName raceIdentifier;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.sap.sailing.server.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class ShardingLeaderBoardEncodingTest {
|
||||
@Test
|
||||
public void testEncoding() {
|
||||
Assert.assertEquals("/leaderboard/pureascistring", ShardingType.LEADERBOARDNAME.encodeIfNeeded("pureascistring"));
|
||||
Assert.assertEquals("/leaderboard/unpure_asci_string", ShardingType.LEADERBOARDNAME.encodeIfNeeded("unpure asci string"));
|
||||
Assert.assertEquals("/leaderboard/c_dille", ShardingType.LEADERBOARDNAME.encodeIfNeeded("cédille"));
|
||||
Assert.assertEquals("/leaderboard/Hello_World", ShardingType.LEADERBOARDNAME.encodeIfNeeded("Hello+World"));
|
||||
Assert.assertEquals("/leaderboard/Hello_World_", ShardingType.LEADERBOARDNAME.encodeIfNeeded("Hello(World)"));
|
||||
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -126,12 +126,12 @@ public class RegattaByKeywordSearchService {
|
||||
*
|
||||
* @param leaderboard the leaderboard to get the matching events for
|
||||
* @param leaderboardGroup the LeaderboardGroup hosting the leaderboard
|
||||
* @param events all events hosting the LeaderboardGroup
|
||||
* @param events all events hosting the LeaderboardGroup; may be {@code null}; if {@code null}, result will be {@code null}
|
||||
* @return the best matching events for the given Leaderboard/LeaderboardGroup
|
||||
*/
|
||||
private Set<Event> filterEventsForLeaderboard(Leaderboard leaderboard, LeaderboardGroup leaderboardGroup, Set<Event> events) {
|
||||
final Set<Event> result;
|
||||
if (leaderboardGroup.hasOverallLeaderboard()) {
|
||||
if (events != null && leaderboardGroup.hasOverallLeaderboard()) {
|
||||
CourseArea defaultCourseArea = leaderboard.getDefaultCourseArea();
|
||||
Set<Event> preResult = null;
|
||||
if (defaultCourseArea != null) {
|
||||
|
||||
@@ -29,6 +29,17 @@
|
||||
This can be done from the adminconsole->tracked races->audio & videos tab</li>
|
||||
<li>In raceboard when you edit a video you do not need to explicitly press "Preview" before saving anymore.
|
||||
Saving now implicitly applies the changes.</li>
|
||||
<li>The URLs of our GWT services are extended to include a leaderboard name if a call is context sensitive to a specific leaderboard.
|
||||
This does not affect the functionality of any service but allows us to setup load balancing with leaderboard specific routing.
|
||||
The leaderboard names put into the URL are cleaned: Any character that isn't a latin upper/lowercase letter or digit is replaced with an underscore character.
|
||||
Currently, the following leaderboard specific URLs are used:
|
||||
<ul>
|
||||
<li>/gwt/service/sailing/leaderboard/[CLEANED-LEADERBOARD-NAME]</li>
|
||||
<li>/gwt/service/dispatch/leaderboard/[CLEANED-LEADERBOARD-NAME]</li>
|
||||
</ul>
|
||||
Be aware that request without leaderboard suffix may be sent from pages that do not show leaderboard specific contents.
|
||||
Due to this it is required to define a fallback rule for any unqualified request.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="articleSubheadline">May 2018</h2>
|
||||
|
||||
@@ -57,6 +57,7 @@ Export-Package: com.google.gwt.user.client.rpc.core.java.util,
|
||||
com.sap.sse.gwt.dispatch.client.system,
|
||||
com.sap.sse.gwt.dispatch.client.system.batching,
|
||||
com.sap.sse.gwt.dispatch.client.system.caching,
|
||||
com.sap.sse.gwt.dispatch.client.system.routing,
|
||||
com.sap.sse.gwt.dispatch.client.transport.gwtrpc,
|
||||
com.sap.sse.gwt.dispatch.servlets,
|
||||
com.sap.sse.gwt.dispatch.shared.caching,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.sap.sse.gwt.client;
|
||||
|
||||
import com.sap.sse.gwt.dispatch.client.system.DispatchSystemDefaultImpl;
|
||||
|
||||
/**
|
||||
* Interface used to append a routing suffix to target url
|
||||
* in GWT RPC service instances and in {@link DispatchSystemDefaultImpl}
|
||||
*/
|
||||
public interface ServiceRoutingProvider {
|
||||
|
||||
String routingSuffixPath();
|
||||
}
|
||||
+39
-6
@@ -1,11 +1,14 @@
|
||||
package com.sap.sse.gwt.dispatch.client.system;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sse.gwt.client.ServiceRoutingProvider;
|
||||
import com.sap.sse.gwt.dispatch.client.system.batching.AutomaticBatchingDispatch;
|
||||
import com.sap.sse.gwt.dispatch.client.system.caching.CachingDispatch;
|
||||
import com.sap.sse.gwt.dispatch.client.transport.DefaultTransport;
|
||||
@@ -27,8 +30,11 @@ public abstract class DispatchSystemDefaultImpl<CTX extends DispatchContext> imp
|
||||
ProvidesServerTime {
|
||||
private final Logger LOG = Logger.getLogger(DispatchSystemDefaultImpl.class.getName());
|
||||
private final DefaultTransport<CTX> simpleDispatch;
|
||||
private final DispatchSystemAsync<CTX> dispatch;
|
||||
|
||||
private final DispatchSystemAsync<CTX> defaultDispatch;
|
||||
private final Map<String,DispatchSystemAsync<CTX>> routingRegistry = new HashMap<>();
|
||||
private final boolean processResultsScheduled;
|
||||
private final String dispatchRPCPath;
|
||||
|
||||
public DispatchSystemDefaultImpl(String dispatchRPCPath) {
|
||||
this(dispatchRPCPath, false);
|
||||
}
|
||||
@@ -43,10 +49,25 @@ public abstract class DispatchSystemDefaultImpl<CTX extends DispatchContext> imp
|
||||
* use a {@link Scheduler} to process the results
|
||||
*/
|
||||
public DispatchSystemDefaultImpl(String dispatchRPCPath, boolean processResultsScheduled) {
|
||||
this.dispatchRPCPath = dispatchRPCPath;
|
||||
this.processResultsScheduled = processResultsScheduled;
|
||||
simpleDispatch = new DefaultTransport<CTX>(dispatchRPCPath);
|
||||
dispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(
|
||||
simpleDispatch, processResultsScheduled));
|
||||
LOG.finest("Started dispatch system for " + dispatchRPCPath);
|
||||
defaultDispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(simpleDispatch, processResultsScheduled));
|
||||
LOG.finest("Started default dispatch system for " + dispatchRPCPath);
|
||||
}
|
||||
|
||||
private DispatchSystemAsync<CTX> createDispatchFor(String routing) {
|
||||
final StringBuilder destinationUrlBuilder = new StringBuilder(dispatchRPCPath);
|
||||
if (routing != null && !routing.isEmpty()) {
|
||||
if (!dispatchRPCPath.endsWith("/")) {
|
||||
destinationUrlBuilder.append("/");
|
||||
}
|
||||
destinationUrlBuilder.append(routing.startsWith("/") ? routing.substring(1) : routing);
|
||||
}
|
||||
DefaultTransport<CTX> transport = new DefaultTransport<CTX>(destinationUrlBuilder.toString());
|
||||
DispatchSystemAsync<CTX> dispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(
|
||||
transport, processResultsScheduled));
|
||||
return dispatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,7 +87,19 @@ public abstract class DispatchSystemDefaultImpl<CTX extends DispatchContext> imp
|
||||
callback.onSuccess(result);
|
||||
}
|
||||
};
|
||||
dispatch.execute(action, wrappedCallback);
|
||||
final DispatchSystemAsync<CTX> dispatchToUse;
|
||||
if (action instanceof ServiceRoutingProvider) {
|
||||
ServiceRoutingProvider providesDispatchRoutingKey = (ServiceRoutingProvider) action;
|
||||
String routingPath = providesDispatchRoutingKey.routingSuffixPath();
|
||||
|
||||
dispatchToUse = routingRegistry.computeIfAbsent(routingPath, this::createDispatchFor);
|
||||
|
||||
LOG.fine("Using routed dispatch for path "+ routingPath);
|
||||
} else {
|
||||
LOG.fine("Using default dispatch for "+ action.getClass().getName());
|
||||
dispatchToUse = defaultDispatch;
|
||||
}
|
||||
dispatchToUse.execute(action, wrappedCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: TracTrac Client module
|
||||
Bundle-SymbolicName: com.tractrac.clientmodule
|
||||
Bundle-Version: 3.10.0
|
||||
Bundle-Version: 3.10.1
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ClassPath: .,
|
||||
lib/TracAPI.jar
|
||||
@@ -41,6 +41,7 @@ Export-Package: com.tractrac.asio.lib.api,
|
||||
com.tractrac.dataflow.lib.prov.stored.tcp.put,
|
||||
com.tractrac.dataflow.lib.spi,
|
||||
com.tractrac.dataflow.lib.spi.authentication,
|
||||
com.tractrac.datatypes.lib.api.sensor,
|
||||
com.tractrac.model.lib.api,
|
||||
com.tractrac.model.lib.api.attachment,
|
||||
com.tractrac.model.lib.api.data,
|
||||
@@ -59,10 +60,17 @@ Export-Package: com.tractrac.asio.lib.api,
|
||||
com.tractrac.model.lib.impl.spatial,
|
||||
com.tractrac.model.server.lib.api,
|
||||
com.tractrac.model.server.lib.api.cache,
|
||||
com.tractrac.model.server.lib.api.commands,
|
||||
com.tractrac.model.server.lib.api.controlpassing,
|
||||
com.tractrac.model.server.lib.api.devices,
|
||||
com.tractrac.model.server.lib.api.gms,
|
||||
com.tractrac.model.server.lib.api.loype,
|
||||
com.tractrac.model.server.lib.api.notifier,
|
||||
com.tractrac.model.server.lib.api.position,
|
||||
com.tractrac.model.server.lib.api.raceobject,
|
||||
com.tractrac.model.server.lib.api.route,
|
||||
com.tractrac.model.server.lib.api.sensor,
|
||||
com.tractrac.model.server.lib.api.view,
|
||||
com.tractrac.osgi,
|
||||
com.tractrac.subscription.app.tracapi,
|
||||
com.tractrac.subscription.lib.api,
|
||||
|
||||
@@ -15,6 +15,29 @@ It contains also some files:
|
||||
|
||||
- test.sh -> script that compiles the code in the src folder, creates the test.jar library and execute the code of the example.
|
||||
- Manifest.txt -> manifest used to create the test.jar file
|
||||
|
||||
********************************************
|
||||
************* TracAPI 3.10.1 ***************
|
||||
********************************************
|
||||
This is a final version.It fixes bugs in the implementation and it adds a some features.
|
||||
It keeps the backward compatibility.
|
||||
|
||||
Release date: 28/06/2018
|
||||
Build number: 35a26e503339fff26fe984617e5190a18438e10b
|
||||
|
||||
1) Features
|
||||
|
||||
- Adding a method to retrieve positions by class id (Requested by Chris Terkelsen, 07/05/2018)
|
||||
|
||||
2) Bugs
|
||||
|
||||
- When the client is offline, if it tries to load a race it gets a RaceLoadingException. But then,
|
||||
when the client is online again, it can't reuse the same race because it is in an internal wrong
|
||||
status (Reported by Thomas Scott, 19/06/2018)
|
||||
- The live delay is not propagated (sometimes). This feature has been reimplemented and now the
|
||||
value is attached and send with the race object using the same approach used to transmit the race
|
||||
start time or the tracking start time (Reported by Axel Uhl, 19/06/2018)
|
||||
|
||||
********************************************
|
||||
************* TracAPI 3.10.0 ***************
|
||||
********************************************
|
||||
|
||||
Loaded 100 of 123 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user