mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-15 06:49:56 +00:00
Merge remote-tracking branch 'origin/master' into maneuver_refactoring
This commit is contained in:
commit
9015b5edc6
198 files changed
+3058
-1619
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,
|
||||
|
||||
+3
@@ -31,6 +31,7 @@ public enum BoatClassMasterdata {
|
||||
CANOE_TAIFUN ("Canoe Taifun", true, 5.20, 1.32, BoatHullType.MONOHULL, false, "Taifun", "Taifun Kanu", "Kanu Taifun"),
|
||||
CONTENDER ("Contender", true, 4.88, 1.42, BoatHullType.MONOHULL, false),
|
||||
CC_30 ("C&C 30", true, 9.12, 3.25, BoatHullType.MONOHULL, true),
|
||||
CLUB_SWAN_50 ("Club Swan 50", true, 16.74, 4.20, BoatHullType.MONOHULL, true, "ClubSwan50"),
|
||||
D_ONE ("D-One", true, 4.23, 2.31, BoatHullType.MONOHULL, true, "Devoti D-One", "DOne", "D_One"),
|
||||
DRAGON_INT ("Dragon Int.", true, 8.89, 1.96, BoatHullType.MONOHULL, true, "Drachen", "Dragon"),
|
||||
DELPHIA_24 ("Delphia 24", true, 7.70, 2.50, BoatHullType.MONOHULL, true, "Delphia 24 One Design", "Delphia 24 OD"),
|
||||
@@ -44,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"),
|
||||
@@ -115,6 +117,7 @@ public enum BoatClassMasterdata {
|
||||
TOM_28_MAX ("Tom 28 MAX", true, 8.48, 2.48, BoatHullType.MONOHULL, true, "Tom 28"),
|
||||
TRIAS ("Trias", true, 9.20, 2.12, BoatHullType.MONOHULL, true),
|
||||
TP52 ("TP52", true, 15.85, 4.35, BoatHullType.MONOHULL, true, "TP 52", "Transpac 52", "Transpac52"),
|
||||
VAURIEN ("Vaurien", true, 4.08, 1.47, BoatHullType.MONOHULL, true),
|
||||
VENT_D_OUEST ("Vent d'Ouest", true, 5.85, 1.75, BoatHullType.MONOHULL, true, "VENTDOUEST", "VENTD'OUEST"),
|
||||
VIPER_640 ("Viper 640", true, 6.43, 2.49, BoatHullType.MONOHULL, true),
|
||||
VO60 ("VO60", true, 19.5, 5.25, BoatHullType.MONOHULL, true, "Volvo Ocean 60", "VolvoOcean60", "W60", "Whitbread60", "Whitbread 60"),
|
||||
|
||||
+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.warning("Empty sharding constraint");
|
||||
return;
|
||||
}
|
||||
final ThreadLocal<String> shardingHolder = shardingMap.get(type);
|
||||
if (shardingHolder == null) {
|
||||
logger.log(Level.WARNING, "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.get(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
|
||||
|
||||
@@ -29,7 +29,7 @@ html {
|
||||
|
||||
|
||||
body {
|
||||
background: url(images/spectatorview-bg.png) no-repeat left top #ebebeb;
|
||||
background: #eee;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
@@ -150,11 +150,6 @@ input.magnifier {
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.mainPanel {
|
||||
width: 100%;
|
||||
margin-left: 13px;
|
||||
}
|
||||
|
||||
.errorLabel {
|
||||
color: #FF0000;
|
||||
}
|
||||
@@ -221,15 +216,32 @@ input.magnifier {
|
||||
top: 9px;
|
||||
}
|
||||
|
||||
.groupingProvider {
|
||||
padding: 3px 0px;
|
||||
}
|
||||
|
||||
.groupingProviderElement {
|
||||
margin: 2px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.statisticProvider {
|
||||
padding: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.statisticProviderElement {
|
||||
margin: 10px 2px 2px 2px;
|
||||
margin: 2px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.statisticSuggestBoxPopup {
|
||||
z-index: 2;
|
||||
}
|
||||
.statisticSuggestBoxPopup .suggestPopupContent {
|
||||
max-height: 700px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.definitionProviderControls {
|
||||
margin: 2px;
|
||||
}
|
||||
@@ -238,14 +250,17 @@ input.magnifier {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.queryProviderElementLabel {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.queryDefinitionViewerContent {
|
||||
background-color: white;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.statisticSuggestBoxPopup .suggestPopupContent {
|
||||
max-height: 700px;
|
||||
overflow-y: scroll;
|
||||
.filterDimensionsTitleLabel {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.filterFilterDimensionsPanel {
|
||||
@@ -254,7 +269,6 @@ input.magnifier {
|
||||
|
||||
.dimensionFilterSelectionTablesContainer {
|
||||
overflow-x: auto;
|
||||
border-left: 2px solid #6f7277;
|
||||
}
|
||||
|
||||
.dimensionFilterSelectionHeader {
|
||||
@@ -267,6 +281,58 @@ input.magnifier {
|
||||
text-shadow: #ddf 1px 1px 0;
|
||||
}
|
||||
|
||||
.dimensionFilterSelectionTable {
|
||||
border-top: 2px solid #6f7277;
|
||||
.dataMiningBorderTop {
|
||||
border-top: 2px solid #6f7277;
|
||||
}
|
||||
.dataMiningBorderLeft {
|
||||
border-left: 2px solid #6f7277;
|
||||
}
|
||||
.dataMiningBorderBottom {
|
||||
border-border: 2px solid #6f7277;
|
||||
}
|
||||
.dataMiningBorderRight {
|
||||
border-right: 2px solid #6f7277;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-VDragger {
|
||||
background: #fff url(images/thumb_horz.png) center center no-repeat;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
left: 0 !important;
|
||||
top: 0 !important;
|
||||
border: none;
|
||||
border-radius: 0px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-HDragger {
|
||||
background: #fff url(images/thumb_vertical.png) center center no-repeat;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
left: 0 !important;
|
||||
top: 0 !important;
|
||||
border: none;
|
||||
border-radius: 0px;
|
||||
margin: 0px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dataMiningMarginBase {
|
||||
margin: 0px 5px;
|
||||
}
|
||||
.dataMiningMarginLeft {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.dataMiningMarginRight {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.resultsPresenterTabHeader * {
|
||||
display: inline-block;
|
||||
margin: 0px 3px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.emphasizedLabel {
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.github.sdbg.debug.core.chromeLaunchConfig">
|
||||
<stringAttribute key="applicationArguments" value=""/>
|
||||
<stringAttribute key="applicationName" value=""/>
|
||||
<booleanAttribute key="launchFile" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.gwt.ui"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="projectName" value="com.sap.sailing.gwt.ui"/>
|
||||
<booleanAttribute key="showLaunchOutput" value="false"/>
|
||||
<stringAttribute key="url" value="http://127.0.0.1:8888/gwt/DataMining.html"/>
|
||||
<stringAttribute key="urlQueryParams" value=""/>
|
||||
</launchConfiguration>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
+2
@@ -17,6 +17,7 @@ import com.sap.sailing.gwt.autoplay.client.utils.AutoplayHelper;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
@@ -35,6 +36,7 @@ public class IdleRaceLeaderboard extends FiresPlaceNode {
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
leaderboardTimer.setTime(MillisecondsTimePoint.now().asMillis());
|
||||
leaderboardTimer.play();
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> settings = cf.getAutoPlayCtxSignalError()
|
||||
.getAutoplaySettings();
|
||||
|
||||
+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);
|
||||
|
||||
+3
@@ -24,6 +24,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.raceboard.RaceBoardPanel;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceboardDataDTO;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
@@ -54,6 +55,8 @@ public class LiveRaceBoardNode extends FiresPlaceNode implements RaceTimesInfoPr
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
raceboardTimer.setTime(MillisecondsTimePoint.now().asMillis());
|
||||
raceboardTimer.play();
|
||||
raceTimesInfoProvider.addRaceIdentifier(cf.getAutoPlayCtxSignalError().getLifeOrPreLiveRace(), true);
|
||||
|
||||
PerspectiveCompositeSettings<AutoplayPerspectiveOwnSettings> settings = cf.getAutoPlayCtxSignalError().getAutoplaySettings();
|
||||
|
||||
+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>
|
||||
|
||||
+3
@@ -45,6 +45,7 @@ public class BoatClassImageResolver {
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CANOE_TAIFUN.getDisplayName(), imageResources.CanoeTaifunIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CONTENDER.getDisplayName(), imageResources.ContenderIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CC_30.getDisplayName(), imageResources.CC30Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.CLUB_SWAN_50.getDisplayName(), imageResources.CLUBSWAN50Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.DELPHIA_24.getDisplayName(), imageResources.Delphia24Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.DRAGON_INT.getDisplayName(), imageResources.DragonIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.DYAS.getDisplayName(), imageResources.DyasIcon());
|
||||
@@ -58,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());
|
||||
@@ -126,6 +128,7 @@ public class BoatClassImageResolver {
|
||||
boatClassIconsMap.put(BoatClassMasterdata.TOM_28_MAX.getDisplayName(), imageResources.Tom28MaxIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.TP52.getDisplayName(), imageResources.TP52Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.TRIAS.getDisplayName(), imageResources.TriasIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.VAURIEN.getDisplayName(), imageResources.VaurienIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.VENT_D_OUEST.getDisplayName(), imageResources.VentdOuestIcon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.VIPER_640.getDisplayName(), imageResources.Viper640Icon());
|
||||
boatClassIconsMap.put(BoatClassMasterdata.VX_ONE.getDisplayName(), imageResources.VXOneIcon());
|
||||
|
||||
+12
@@ -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();
|
||||
@@ -396,6 +400,10 @@ public interface BoatClassImageResources extends ClientBundle {
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource CC30Icon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/CLUBSWAN50.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource CLUBSWAN50Icon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/GP_26.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource GP26Icon();
|
||||
@@ -431,4 +439,8 @@ public interface BoatClassImageResources extends ClientBundle {
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/RUNNING.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource RunningIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/VAURIEN.png")
|
||||
@ImageOptions(preventInlining = true)
|
||||
ImageResource VaurienIcon();
|
||||
}
|
||||
+1
@@ -25,6 +25,7 @@
|
||||
|
||||
.tabExtension {
|
||||
float: right;
|
||||
margin-top: .5em;
|
||||
}
|
||||
|
||||
.tabExtension > * {
|
||||
|
||||
+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) {
|
||||
|
||||
+1
-1
@@ -20,12 +20,12 @@ public class SailorInfo extends Composite {
|
||||
FlowPanel panel = new FlowPanel();
|
||||
Style panelStyle = panel.getElement().getStyle();
|
||||
panelStyle.setDisplay(Display.INLINE_BLOCK);
|
||||
panelStyle.setVerticalAlign(VerticalAlign.BOTTOM);
|
||||
|
||||
Label sailorInfoLabel = new Label();
|
||||
sailorInfoLabel.getElement().setInnerHTML(i18n.sailorInfoLongText().replace("\n", "<br />"));
|
||||
Style labelStyle = sailorInfoLabel.getElement().getStyle();
|
||||
labelStyle.setDisplay(Display.INLINE_BLOCK);
|
||||
sailorInfoLabel.getElement().getStyle().setMarginTop(0.5, Unit.EM);
|
||||
sailorInfoLabel.getElement().getStyle().setMarginRight(0.5, Unit.EM);
|
||||
panel.add(sailorInfoLabel);
|
||||
|
||||
|
||||
-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);
|
||||
|
||||
+10
-8
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.home.desktop.places.event.regatta;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.dom.client.Style.TextTransform;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
@@ -65,7 +66,12 @@ public class TabletAndDesktopRegattaEventView extends Composite implements Event
|
||||
racesTabUi = new RegattaRacesTabView(flagImageResolver);
|
||||
regattaOverviewTabUi = new RegattaOverviewTabView(flagImageResolver);
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
|
||||
String sailorsInfoURL = currentPresenter.getEventDTO().getSailorsInfoWebsiteURL();
|
||||
if (sailorsInfoURL != null && !sailorsInfoURL.isEmpty()) {
|
||||
tabPanelUi.addTabExtension(new SailorInfo(sailorsInfoURL));
|
||||
}
|
||||
|
||||
if(currentPresenter.getEventDTO().getType() == EventType.SERIES) {
|
||||
final PlaceNavigation<SeriesDefaultPlace> currentEventSeriesNavigation = currentPresenter.getCurrentEventSeriesNavigation();
|
||||
Anchor seriesAnchor = new Anchor(i18n.overallLeaderboardSelection());
|
||||
@@ -82,14 +88,10 @@ public class TabletAndDesktopRegattaEventView extends Composite implements Event
|
||||
seriesAnchor.setStyleName(SharedResources.INSTANCE.mainCss().button());
|
||||
seriesAnchor.addStyleName(SharedResources.INSTANCE.mainCss().buttonprimary());
|
||||
Style style = seriesAnchor.getElement().getStyle();
|
||||
style.setFontSize(16, Unit.PX);
|
||||
style.setPadding(0.75, Unit.EM);
|
||||
style.setPaddingLeft(0.75, Unit.EM);
|
||||
style.setPaddingRight(0.75, Unit.EM);
|
||||
style.setTextTransform(TextTransform.UPPERCASE);
|
||||
tabPanelUi.addTabExtension(seriesAnchor);
|
||||
} else {
|
||||
String sailorsInfoURL = currentPresenter.getEventDTO().getSailorsInfoWebsiteURL();
|
||||
if(sailorsInfoURL != null && ! sailorsInfoURL.isEmpty()) {
|
||||
tabPanelUi.addTabExtension(new SailorInfo(sailorsInfoURL));
|
||||
}
|
||||
}
|
||||
|
||||
final Iterable<SpotDTO> spots = currentPresenter.getEventDTO().getAllWindFinderSpotIdsUsedByEvent();
|
||||
|
||||
+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) {
|
||||
|
||||
+23
-9
@@ -3,8 +3,11 @@ package com.sap.sailing.gwt.home.desktop.places.fakeseries;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
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 +15,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 +46,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 +87,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,
|
||||
@@ -98,8 +104,10 @@ public class EventSeriesAnalyticsDataManager {
|
||||
MultiRaceLeaderboardSettings leaderboardSettings,
|
||||
String preselectedLeaderboardName, String leaderboardGroupName,
|
||||
String metaLeaderboardName, boolean showRaceDetails, boolean autoExpandLastRaceColumn, Iterable<DetailType> availableDetailTypes) {
|
||||
if(multiLeaderboardPanel == null) {
|
||||
multiLeaderboardPanel = new MultiLeaderboardProxyPanel(parent, context, sailingService, metaLeaderboardName,
|
||||
if (multiLeaderboardPanel == null) {
|
||||
final Function<String, SailingServiceAsync> sailingServiceFactory = leaderBoardName -> sailingCF
|
||||
.getSailingService(() -> leaderBoardName);
|
||||
multiLeaderboardPanel = new MultiLeaderboardProxyPanel(parent, context, sailingServiceFactory, metaLeaderboardName,
|
||||
asyncActionsExecutor, timer, true /* isEmbedded */,
|
||||
preselectedLeaderboardName, errorReporter, StringMessages.INSTANCE,
|
||||
showRaceDetails, autoExpandLastRaceColumn, leaderboardSettings, flagImageResolver, availableDetailTypes);
|
||||
@@ -179,4 +187,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>
|
||||
|
||||
+1
-4
@@ -19,13 +19,10 @@
|
||||
<li>Selecting a filter dimension adds a table containing the available values of the selected dimension. The order of
|
||||
the value tables is equal to the order of the dimensions list.
|
||||
</li>
|
||||
<li>Note that the selection of the filter dimensions follows the <q>table with checkbox column</q> pattern. So simply clicking on a
|
||||
dimension will result in deselecting all previously selected dimensions, removing possible filter values. Clicking on the
|
||||
checkbox column or using <q>ctrl+click</q> is advised.
|
||||
</li>
|
||||
<li>Each filter value table now has its own scroll-bar.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The grouping dimensions are now ordered alphabetically.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">April 2018</h5>
|
||||
|
||||
+9
-5
@@ -6,6 +6,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
@@ -39,9 +40,11 @@ public abstract class AbstractEventView<P extends EventViewBase.Presenter> exten
|
||||
static class AbstractEventViewLayout {
|
||||
@UiField(provided = true) EventHeader eventHeaderUi;
|
||||
@UiField Quickfinder quickFinderUi;
|
||||
@UiField SimpleInfoBlock simpleInfoUi;
|
||||
@UiField SimpleInfoBlock sailorInfoUi;
|
||||
@UiField SimpleInfoBlock seriesNavigationoUi;
|
||||
@UiField DivElement windfinderWrapperUi;
|
||||
@UiField(provided = true) WindfinderControl windfinderUi;
|
||||
@UiField SimplePanel viewContentUi;;
|
||||
@UiField SimplePanel viewContentUi;
|
||||
|
||||
private AbstractEventViewLayout(EventViewDTO event, String regattaName, PlaceNavigation<?> logoNavigation) {
|
||||
this.eventHeaderUi = new EventHeader(event, regattaName, logoNavigation);
|
||||
@@ -125,18 +128,19 @@ public abstract class AbstractEventView<P extends EventViewBase.Presenter> exten
|
||||
|
||||
@Override
|
||||
public void setSailorInfos(String description, String buttonLabel, String url) {
|
||||
layout.simpleInfoUi.setDescription(SafeHtmlUtils.fromString(description.replace("\n", " ")));
|
||||
layout.simpleInfoUi.setAction(buttonLabel, url);
|
||||
layout.sailorInfoUi.setDescription(SafeHtmlUtils.fromString(description.replace("\n", " ")));
|
||||
layout.sailorInfoUi.setAction(buttonLabel, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindfinderNavigations(Iterable<SpotDTO> spotData) {
|
||||
layout.windfinderWrapperUi.getStyle().clearDisplay();
|
||||
layout.windfinderUi.setSpotData(spotData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeriesNavigation(String buttonLabel, PlaceNavigation<?> placeNavigation) {
|
||||
layout.simpleInfoUi.setAction(buttonLabel, placeNavigation);
|
||||
layout.seriesNavigationoUi.setAction(buttonLabel, placeNavigation);
|
||||
}
|
||||
|
||||
}
|
||||
+10
-4
@@ -7,9 +7,12 @@
|
||||
.headerWrapper {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.windfinderWrapper {
|
||||
padding-bottom: 10px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
.windfinder {
|
||||
display: block;
|
||||
margin: 0 10px 10px;
|
||||
width: 100%;
|
||||
border-radius: .384615384615385em;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -18,8 +21,11 @@
|
||||
<div class="{style.headerWrapper}">
|
||||
<mp:eventheader.EventHeader ui:field="eventHeaderUi" />
|
||||
<mp:quickfinder.Quickfinder ui:field="quickFinderUi" />
|
||||
<mp:simpleinfoblock.SimpleInfoBlock ui:field="simpleInfoUi" />
|
||||
<sp:windfinder.WindfinderControl ui:field="windfinderUi" addStyleNames="{style.windfinder}" />
|
||||
<mp:simpleinfoblock.SimpleInfoBlock ui:field="sailorInfoUi" />
|
||||
<mp:simpleinfoblock.SimpleInfoBlock ui:field="seriesNavigationoUi" />
|
||||
<div class="{style.windfinderWrapper}" style="display:none;" ui:field="windfinderWrapperUi">
|
||||
<sp:windfinder.WindfinderControl ui:field="windfinderUi" addStyleNames="{style.windfinder}" />
|
||||
</div>
|
||||
</div>
|
||||
<g:SimplePanel ui:field="viewContentUi"></g:SimplePanel>
|
||||
</g:HTMLPanel>
|
||||
|
||||
+1
-1
@@ -30,11 +30,11 @@ public class RegattaActivity extends AbstractEventActivity<RegattaOverviewPlace>
|
||||
@Override
|
||||
protected EventViewBase initView() {
|
||||
final AbstractEventOverview view = new RegattaOverviewImpl(this, flagImageResolver);
|
||||
initSailorInfo(view);
|
||||
initSeriesNavigation(view);
|
||||
initQuickfinder(view, true);
|
||||
initWindfinderNavigations(view);
|
||||
if (!isMultiRegattaEvent()) {
|
||||
// initSailorInfo(view);
|
||||
initMedia(view);
|
||||
}
|
||||
return view;
|
||||
|
||||
+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>
|
||||
|
||||
+3
-1
@@ -12,6 +12,8 @@ import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.Notification;
|
||||
import com.sap.sse.gwt.client.Notification.NotificationType;
|
||||
|
||||
public class ErrorMessage extends Composite {
|
||||
|
||||
@@ -42,7 +44,7 @@ public class ErrorMessage extends Composite {
|
||||
}
|
||||
|
||||
this.errorMessageDetail.setInnerText(errorMessageDetail);
|
||||
Window.setStatus(errorMessageDetail);
|
||||
Notification.notify(errorMessageDetail, NotificationType.WARNING);
|
||||
}
|
||||
|
||||
public void addReloadPageButtonStyleNames(String styleNames) {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
text-decoration: none;
|
||||
vertical-align: bottom;
|
||||
padding-left: 1em;
|
||||
padding-right: 0.5em
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.windfindercontrol_text, .windfindercontrol_icon {
|
||||
display: inline-block;
|
||||
|
||||
+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) {
|
||||
|
||||
+3
-2
@@ -4,7 +4,6 @@ import java.util.Date;
|
||||
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
@@ -14,6 +13,8 @@ import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceCourseDTO;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.Notification;
|
||||
import com.sap.sse.gwt.client.Notification.NotificationType;
|
||||
|
||||
/**
|
||||
* A panel that has a race selection (inherited from {@link AbstractRaceManagementPanel}) and which adds a table
|
||||
@@ -41,7 +42,7 @@ public class RaceCourseManagementPanel extends AbstractRaceManagementPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
Window.setStatus(stringMessages.successfullyUpdatedCourse());
|
||||
Notification.notify(stringMessages.successfullyUpdatedCourse(), NotificationType.INFO);
|
||||
refreshSelectedRaceData();
|
||||
}
|
||||
});
|
||||
|
||||
+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);
|
||||
|
||||
+5
-4
@@ -15,7 +15,6 @@ import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.user.cellview.client.CellTable;
|
||||
import com.google.gwt.user.cellview.client.Column;
|
||||
import com.google.gwt.user.cellview.client.TextColumn;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.CaptionPanel;
|
||||
@@ -30,6 +29,8 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.EventBaseDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RemoteSailingServerReferenceDTO;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.Notification;
|
||||
import com.sap.sse.gwt.client.Notification.NotificationType;
|
||||
import com.sap.sse.gwt.client.celltable.BaseCelltable;
|
||||
import com.sap.sse.gwt.client.celltable.EntityIdentityComparator;
|
||||
import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel;
|
||||
@@ -209,7 +210,7 @@ public class RemoteServerInstancesManagementPanel extends SimplePanel {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
refreshSailingServerList();
|
||||
Window.setStatus(stringMessages.successfullyUpdatedSailingServers());
|
||||
Notification.notify(stringMessages.successfullyUpdatedSailingServers(), NotificationType.INFO);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -230,8 +231,8 @@ public class RemoteServerInstancesManagementPanel extends SimplePanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(RemoteSailingServerReferenceDTO result) {
|
||||
filteredServerTablePanel.add(result);
|
||||
Window.setStatus(stringMessages.successfullyUpdatedSailingServers());
|
||||
filteredServerTablePanel.add(result);
|
||||
Notification.notify(stringMessages.successfullyUpdatedSailingServers(), NotificationType.INFO);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+4
-3
@@ -8,7 +8,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.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
@@ -22,6 +21,8 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.TextfieldEntryDialog;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.Notification;
|
||||
import com.sap.sse.gwt.client.Notification.NotificationType;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
|
||||
|
||||
@@ -163,7 +164,7 @@ public class ResultImportUrlsManagementPanel extends FlowPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
Window.setStatus(stringMessages.successfullyUpdatedResultImportUrls());
|
||||
Notification.notify(stringMessages.successfullyUpdatedResultImportUrls(), NotificationType.INFO);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -198,7 +199,7 @@ public class ResultImportUrlsManagementPanel extends FlowPanel {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
urlListBox.addItem(url);
|
||||
Window.setStatus(stringMessages.successfullyUpdatedResultImportUrls());
|
||||
Notification.notify(stringMessages.successfullyUpdatedResultImportUrls(), NotificationType.INFO);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+155
-100
@@ -5,14 +5,12 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
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 +33,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,15 +53,22 @@ 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 eventIdBox;
|
||||
private final TextBox jsonUrlBox;
|
||||
private final TextBox hostnameTextbox;
|
||||
private final IntegerBox portIntegerbox;
|
||||
private final List<SwissTimingRaceRecordDTO> availableSwissTimingRaces = new ArrayList<SwissTimingRaceRecordDTO>();
|
||||
private final String manage2sailBaseAPIUrl = "http://manage2sail.com/api/public/links/event/";
|
||||
private final String manage2sailAPIaccessToken = "?accesstoken=bDAv8CwsTM94ujZ";
|
||||
private final String manage2sailUrlAppendix = "&mediaType=json&includeRaces=true";
|
||||
private final String eventIdPattern = "[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}";
|
||||
|
||||
public SwissTimingEventManagementPanel(final SailingServiceAsync sailingService,
|
||||
ErrorReporter errorReporter,
|
||||
@@ -83,7 +88,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
captionPanelConnections.setContentWidget(verticalPanel);
|
||||
captionPanelConnections.setStyleName("bold");
|
||||
|
||||
Grid connectionsGrid = new Grid(5, 2);
|
||||
Grid connectionsGrid = new Grid(6, 2);
|
||||
verticalPanel.add(connectionsGrid);
|
||||
|
||||
previousConfigurations = new HashMap<String, SwissTimingConfigurationDTO>();
|
||||
@@ -102,89 +107,50 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
}
|
||||
});
|
||||
fillConfigurations();
|
||||
|
||||
|
||||
jsonUrlBox = new TextBox();
|
||||
jsonUrlBox.getElement().getStyle().setWidth(50, Unit.EM);
|
||||
|
||||
connectionsGrid.setWidget(0, 0, new Label(stringMessages.swissTimingEvents() + ":"));
|
||||
connectionsGrid.setWidget(0, 1, previousConfigurationsComboBox);
|
||||
connectionsGrid.setWidget(1, 0, new Label("Manage2Sail Event-URL (json):"));
|
||||
connectionsGrid.setWidget(1, 1, jsonUrlBox);
|
||||
|
||||
eventIdBox = new TextBox();
|
||||
eventIdBox.getElement().getStyle().setWidth(30, Unit.EM);
|
||||
eventIdBox.setTitle(stringMessages.manage2SailEventIdBoxTooltip());
|
||||
connectionsGrid.setWidget(1, 0, new Label(stringMessages.manage2SailEventIdBox() + ":"));
|
||||
connectionsGrid.setWidget(1, 1, eventIdBox);
|
||||
eventIdBox.addChangeHandler(event -> {
|
||||
if (eventIdBox.getValue() != "") {
|
||||
updateUrlFromEventId(eventIdBox.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
connectionsGrid.setWidget(2, 0, new Label(stringMessages.manage2SailEventURLBox() + ":"));
|
||||
connectionsGrid.setWidget(2, 1, jsonUrlBox);
|
||||
jsonUrlBox.addChangeHandler(event -> {
|
||||
if (jsonUrlBox.getValue() != "") {
|
||||
updateEventIdFromUrl(jsonUrlBox.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
hostnameTextbox = new TextBox();
|
||||
portIntegerbox = new IntegerBox();
|
||||
|
||||
connectionsGrid.setWidget(2, 0, new Label(stringConstants.hostname() + ":"));
|
||||
connectionsGrid.setWidget(2, 1, hostnameTextbox);
|
||||
connectionsGrid.setWidget(3, 0, new Label(stringConstants.hostname() + ":"));
|
||||
connectionsGrid.setWidget(3, 1, hostnameTextbox);
|
||||
|
||||
connectionsGrid.setWidget(3, 0, new Label(stringConstants.port() + ":"));
|
||||
connectionsGrid.setWidget(3, 1, portIntegerbox);
|
||||
connectionsGrid.setWidget(4, 0, new Label(stringMessages.manage2SailPort() + ":"));
|
||||
connectionsGrid.setWidget(4, 1, portIntegerbox);
|
||||
|
||||
Button btnListRaces = new Button(stringConstants.listRaces());
|
||||
connectionsGrid.setWidget(4, 1, btnListRaces);
|
||||
connectionsGrid.setWidget(5, 1, btnListRaces);
|
||||
btnListRaces.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
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 +202,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 +212,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 +232,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, stringConstants.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,
|
||||
@@ -318,6 +348,31 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function tries to infer a valid JsonUrl for any input given that matches the pattern of an event Id from
|
||||
* M2S. If there is an event id detected the Json Url gets updated and the event Id textbox is filled with the
|
||||
* detected event Id. The ID pattern is defined in {@link eventIdPattern}.
|
||||
*/
|
||||
private void updateUrlFromEventId(String eventIdTextbox) {
|
||||
if (eventIdTextbox.matches(".*" + eventIdPattern + ".*")) {
|
||||
final String inferredEventId = eventIdTextbox.replaceFirst(".*(" + eventIdPattern + ").*", "$1");
|
||||
jsonUrlBox.setValue(
|
||||
manage2sailBaseAPIUrl + inferredEventId + manage2sailAPIaccessToken + manage2sailUrlAppendix);
|
||||
eventIdBox.setValue(inferredEventId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #updateUrlFromEventId} this function tries to extract a M2S event Id by looking at the given
|
||||
* url in the Json Url Textbox. The value of {@link eventIdBox} is then set to the event ID inferred from the Json Url.
|
||||
*/
|
||||
private void updateEventIdFromUrl(String jsonUrlTextBox) {
|
||||
if (jsonUrlTextBox.matches("http://manage2sail.com/.*" + eventIdPattern + ".*")) {
|
||||
final String inferredEventId = jsonUrlTextBox.replaceFirst(".*(" + eventIdPattern + ").*", "$1");
|
||||
eventIdBox.setValue(inferredEventId);
|
||||
}
|
||||
}
|
||||
|
||||
private ListHandler<SwissTimingRaceRecordDTO> getRaceTableColumnSortHandler(List<SwissTimingRaceRecordDTO> raceRecords,
|
||||
Column<SwissTimingRaceRecordDTO, ?> regattaNameColumn, Column<SwissTimingRaceRecordDTO, ?> seriesNameColumn,
|
||||
Column<SwissTimingRaceRecordDTO, ?> nameColumn, Column<SwissTimingRaceRecordDTO, ?> trackingStartColumn,
|
||||
|
||||
+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;
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -153,7 +153,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
|
||||
String legDetailsToShow();
|
||||
String columnMoveUp();
|
||||
String columnMoveDown();
|
||||
String port();
|
||||
String raceStartTimeColumn();
|
||||
String showOnlySelectedCompetitors();
|
||||
String showSelectedCompetitorsInfo();
|
||||
@@ -2076,4 +2075,11 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
|
||||
String multiUrlChangeNewURL();
|
||||
String multiUrlNoPrefixWarning();
|
||||
String multiUrlChangeExplain();
|
||||
String lastEvent(String locationOrVenue);
|
||||
String teaserOverallLinkToolTip();
|
||||
String gender();
|
||||
String manage2SailEventIdBox();
|
||||
String manage2SailEventURLBox();
|
||||
String manage2SailEventIdBoxTooltip();
|
||||
String manage2SailPort();
|
||||
}
|
||||
+9
-3
@@ -153,7 +153,6 @@ overallDetailsToShow=Overall Details
|
||||
legDetailsToShow=Leg Details
|
||||
columnMoveUp=Up
|
||||
columnMoveDown=Down
|
||||
port=Port
|
||||
raceStartTimeColumn=Race Started
|
||||
showOnlySelectedCompetitors=Show only selected competitors
|
||||
showSelectedCompetitorsInfo=Show info box for selected competitors
|
||||
@@ -1870,7 +1869,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 +2068,11 @@ 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
|
||||
gender=Gender
|
||||
manage2SailEventIdBox=Manage2Sail Event ID
|
||||
manage2SailEventURLBox=Manage2Sail EventURL (json)
|
||||
manage2SailEventIdBoxTooltip=Event ID or a URL that contains the event ID from Manage2Sail
|
||||
manage2SailPort=Port
|
||||
+9
-3
@@ -155,7 +155,6 @@ overallDetailsToShow=Regatta-Details
|
||||
legDetailsToShow=Schenkeldetails
|
||||
columnMoveUp=Hoch
|
||||
columnMoveDown=Runter
|
||||
port=Backbord
|
||||
raceStartTimeColumn=Rennstart
|
||||
showOnlySelectedCompetitors=Nur ausgewählte Teilnehmer anzeigen
|
||||
showSelectedCompetitorsInfo=Infobox für ausgewählte Teilnehmer anzeigen
|
||||
@@ -1876,7 +1875,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 +2064,11 @@ 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
|
||||
gender=Geschlecht
|
||||
manage2SailEventId=Manage2Sail Event ID
|
||||
manage2SailEventURL=Manage2Sail Event URL (json)
|
||||
manage2SailEventIdBoxTooltip=Event ID von Manage 2 Sail oder URL die die Event ID beinhaltet
|
||||
manage2SailPort=Port
|
||||
-1
@@ -158,7 +158,6 @@ overallDetailsToShow=Detalles generales
|
||||
legDetailsToShow=Detalles de tramo
|
||||
columnMoveUp=Arriba
|
||||
columnMoveDown=Abajo
|
||||
port=Babor
|
||||
raceStartTimeColumn=Carrera iniciada
|
||||
showOnlySelectedCompetitors=Mostrar solo competidores seleccionados
|
||||
showSelectedCompetitorsInfo=Mostrar cuadro de información para competidores seleccionados
|
||||
|
||||
-1
@@ -158,7 +158,6 @@ overallDetailsToShow=Détails généraux
|
||||
legDetailsToShow=Détails de la portion de parcours
|
||||
columnMoveUp=Dans le lit
|
||||
columnMoveDown=Arrière
|
||||
port=À bâbord
|
||||
raceStartTimeColumn=Course lancée
|
||||
showOnlySelectedCompetitors=Afficher uniquement concurrents sélectionnés
|
||||
showSelectedCompetitorsInfo=Afficher carré d''infos pour concurrents sélectionnés
|
||||
|
||||
-1
@@ -158,7 +158,6 @@ overallDetailsToShow=全体詳細
|
||||
legDetailsToShow=レグ詳細
|
||||
columnMoveUp=上
|
||||
columnMoveDown=下
|
||||
port=ポート
|
||||
raceStartTimeColumn=レーススタート済
|
||||
showOnlySelectedCompetitors=選択した競技者のみ表示
|
||||
showSelectedCompetitorsInfo=選択した競技者の情報ボックスを表示
|
||||
|
||||
-1
@@ -158,7 +158,6 @@ overallDetailsToShow=Detalhes gerais
|
||||
legDetailsToShow=Detalhes da perna
|
||||
columnMoveUp=Para cima
|
||||
columnMoveDown=Para baixo
|
||||
port=Bombordo
|
||||
raceStartTimeColumn=Corrida iniciada
|
||||
showOnlySelectedCompetitors=Visualizar somente os competidores selecionados
|
||||
showSelectedCompetitorsInfo=Visualizar caixa de informações para competidores selecionados
|
||||
|
||||
-1
@@ -158,7 +158,6 @@ overallDetailsToShow=Общие подробности
|
||||
legDetailsToShow=Подробности
|
||||
columnMoveUp=Вверх
|
||||
columnMoveDown=Вниз
|
||||
port=Порт
|
||||
raceStartTimeColumn=Гонка начата
|
||||
showOnlySelectedCompetitors=Показать только выбранных участников
|
||||
showSelectedCompetitorsInfo=Показать окно сведений для выбранных участников
|
||||
|
||||
-1
@@ -158,7 +158,6 @@ overallDetailsToShow=总体详情
|
||||
legDetailsToShow=航段详情
|
||||
columnMoveUp=向上
|
||||
columnMoveDown=向下
|
||||
port=端口
|
||||
raceStartTimeColumn=比赛轮次开始时间
|
||||
showOnlySelectedCompetitors=仅显示选择的参赛队
|
||||
showSelectedCompetitorsInfo=显示所选参赛队的信息框
|
||||
|
||||
+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()) {
|
||||
|
||||
+3
-2
@@ -44,7 +44,8 @@ public class BoatClassVectorGraphicsResolver {
|
||||
BoatClassMasterdata.A_CAT, BoatClassMasterdata.TORNADO, BoatClassMasterdata.FLYING_PHANTOM);
|
||||
BoatClassVectorGraphics keelBoatWithGennaker = new KeelBoatWithGennakerVectorGraphics(BoatClassMasterdata.J70,
|
||||
BoatClassMasterdata.B_ONE, BoatClassMasterdata.J80, BoatClassMasterdata.LASER_SB3, BoatClassMasterdata.LONGTZE,
|
||||
BoatClassMasterdata.RS_FEVA, BoatClassMasterdata.RS_TERA, BoatClassMasterdata.RS100, BoatClassMasterdata.TP52);
|
||||
BoatClassMasterdata.RS_FEVA, BoatClassMasterdata.RS_TERA, BoatClassMasterdata.RS100, BoatClassMasterdata.TP52,
|
||||
BoatClassMasterdata.CLUB_SWAN_50);
|
||||
BoatClassVectorGraphics dinghyWithSpinnaker = new DinghyWithSpinnakerVectorGraphics(BoatClassMasterdata._420,
|
||||
BoatClassMasterdata._470, BoatClassMasterdata._5O5, BoatClassMasterdata.CADET, BoatClassMasterdata.FLYING_DUTCHMAN,
|
||||
BoatClassMasterdata.FOLKBOAT, BoatClassMasterdata.DYAS, BoatClassMasterdata.DRAGON_INT,
|
||||
@@ -53,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, BoatClassMasterdata.VAURIEN);
|
||||
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) {
|
||||
|
||||
Loaded 100 of 198 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user