mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-14 22:43:57 +00:00
Merge branch 'bug4343'
# Conflicts: # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/regatta/analyticstab/RegattaCompetitorAnalyticsTabView.java # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/event/regatta/leaderboardtab/RegattaLeaderboardTabView.java # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/fakeseries/analyticstab/EventSeriesCompetitorAnalyticsTabView.java # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/fakeseries/leaderboardstab/EventSeriesLeaderboardsTabView.java # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/fakeseries/overallleaderboardtab/EventSeriesOverallLeaderboardTabView.java # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardEntryPoint.java # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboardedit/LeaderboardEditPage.java
This commit is contained in:
commit
1bae7e936a
52 files changed
+888
-282
No files matched your search
+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,
|
||||
|
||||
+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;
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.sap.sailing.domain.sharding;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LiveLeaderboardUpdater;
|
||||
|
||||
/**
|
||||
* The sharding context is used to store and verify contraints for a thread.
|
||||
*
|
||||
* This is currently used to verify if a given thread, that is explicitly expected to only
|
||||
* trigger the calculation of a given leaderboard, does trigger the calculation of further/ other
|
||||
* leaderboards.
|
||||
*
|
||||
* It is also used to log warnings if a leaderboard is calculated without predefining the thread constraint.
|
||||
*
|
||||
* The enum {@link ShardingType} lists the known sharding types. Each sharding type defines a prefix that will
|
||||
* be used to identify the sharding type from the request, as implemented in {@link #identifyAndSetShardingConstraint(String)}.
|
||||
*
|
||||
* By calling {@link #setShardingConstraint(ShardingType, String)} it is possible to directly set a thread constraint.
|
||||
* This is useful in background computing code, as in {@link LiveLeaderboardUpdater}
|
||||
*
|
||||
*/
|
||||
public class ShardingContext {
|
||||
private static final Logger logger = Logger.getLogger(ShardingContext.class.getName());
|
||||
|
||||
private static final ConcurrentMap<ShardingType, ThreadLocal<String>> shardingMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Sets the sharding context. The type of sharding will be identified by the prefix.
|
||||
*
|
||||
* @param shardingInfo
|
||||
*/
|
||||
public static ShardingType identifyAndSetShardingConstraint(String shardingInfo) {
|
||||
if (shardingInfo == null || shardingInfo.isEmpty()) {
|
||||
logger.warning("Empty sharding constraint");
|
||||
return null;
|
||||
}
|
||||
ThreadLocal<String> identifiedShardingHolder = null;
|
||||
for (ShardingType shardingType : ShardingType.values()) {
|
||||
if (shardingInfo.startsWith(shardingType.getPrefix())) {
|
||||
identifiedShardingHolder = shardingMap.computeIfAbsent(shardingType, t -> new ThreadLocal<>());
|
||||
checkAndSetShardingInfo(shardingType, shardingInfo, identifiedShardingHolder);
|
||||
return shardingType;
|
||||
}
|
||||
}
|
||||
if (identifiedShardingHolder == null) {
|
||||
logger.warning("Could not identify sharding type for: " + shardingInfo);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide sharding constraint for given sharding type.
|
||||
*
|
||||
* @param shardingType
|
||||
* @param shardingInfo
|
||||
*/
|
||||
public static void setShardingConstraint(ShardingType shardingType, String shardingInfo) {
|
||||
final String encodedShardingInfo = shardingType.encodeIfNeeded(shardingInfo);
|
||||
ThreadLocal<String> shardingHolder = shardingMap.computeIfAbsent(shardingType, t -> new ThreadLocal<>());
|
||||
checkAndSetShardingInfo(shardingType, encodedShardingInfo, shardingHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if provided sharding information name equals shard constraint.
|
||||
*
|
||||
* If the information is null or empty, we log a warning.
|
||||
* If shard does not have a constraint, we log a warning. If
|
||||
* the information provided does not match information previously stored in shard,
|
||||
* we make a severe log entry.
|
||||
*
|
||||
* @param shardingInfo
|
||||
*/
|
||||
public static void checkConstraint(final ShardingType type, final String shardingInfo) {
|
||||
if (shardingInfo == null || shardingInfo.isEmpty()) {
|
||||
logger.severe("Empty sharding constraint");
|
||||
return;
|
||||
}
|
||||
final ThreadLocal<String> shardingHolder = shardingMap.get(type);
|
||||
if (shardingHolder == null) {
|
||||
logger.log(Level.SEVERE, "No current sharding context set for " + type.name(), new RuntimeException());
|
||||
return;
|
||||
}
|
||||
String currentShardingInfo = shardingHolder.get();
|
||||
if (currentShardingInfo == null || currentShardingInfo.isEmpty()) {
|
||||
logger.warning("No current sharding constraint for " + type.name());
|
||||
return;
|
||||
}
|
||||
final String encodedShardingInfo = type.encodeIfNeeded(shardingInfo);
|
||||
if (!encodedShardingInfo.equals(currentShardingInfo)) {
|
||||
logger.log(Level.SEVERE, "Current sharding constraint vialation for " + type.name() + ". Got "
|
||||
+ shardingInfo + ", shard requires " + currentShardingInfo, new RuntimeException());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearShardingConstraint(ShardingType type) {
|
||||
ThreadLocal<String> shardingHolder = shardingMap.remove(type);
|
||||
if (shardingHolder != null) {
|
||||
shardingHolder.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkAndSetShardingInfo(ShardingType shardingType, String encodedShardingInfo,
|
||||
ThreadLocal<String> shardingHolder) {
|
||||
if (encodedShardingInfo == null || encodedShardingInfo.isEmpty()) {
|
||||
logger.log(Level.SEVERE, "Cannot set empty sharding information for " + shardingType.name(),
|
||||
new RuntimeException());
|
||||
}
|
||||
String currentShardingInfo = shardingHolder.get();
|
||||
if (currentShardingInfo == null) {
|
||||
shardingHolder.set(encodedShardingInfo);
|
||||
} else if (!encodedShardingInfo.equals(currentShardingInfo)) {
|
||||
logger.log(Level.SEVERE, "Switching shard constraint for " + shardingType.name()+". Got <<" + encodedShardingInfo +">>, expeted <<"+ currentShardingInfo+">>", new RuntimeException());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
+5
-5
@@ -93,11 +93,11 @@ public class IdleSixtyInchLeaderboardNode extends FiresPlaceNode {
|
||||
|
||||
private void startWithLeaderbaord(final MultiRaceLeaderboardSettings leaderboardSettings,
|
||||
CompetitorSelectionProvider provider, String leaderboardName) {
|
||||
MultiRaceLeaderboardPanel leaderboardPanel = new MultiRaceLeaderboardPanel(null, null, cf.getSailingService(),
|
||||
new AsyncActionsExecutor(), leaderboardSettings, false, provider, timer, null, leaderboardName,
|
||||
cf.getErrorReporter(), StringMessages.INSTANCE, false, null, false, null, false, true, false, false,
|
||||
false, new SixtyInchLeaderboardStyle(true), FlagImageResolverImpl.get(),
|
||||
Arrays.asList(DetailType.values()));
|
||||
MultiRaceLeaderboardPanel leaderboardPanel = new MultiRaceLeaderboardPanel(null, null,
|
||||
cf.getSailingService(() -> leaderboardName), new AsyncActionsExecutor(), leaderboardSettings, false,
|
||||
provider, timer, null, leaderboardName, cf.getErrorReporter(), StringMessages.INSTANCE, false, null,
|
||||
false, null, false, true, false, false, false, new SixtyInchLeaderboardStyle(true),
|
||||
FlagImageResolverImpl.get(), Arrays.asList(DetailType.values()));
|
||||
|
||||
IdleSixtyInchLeaderboardPlace place = new IdleSixtyInchLeaderboardPlace(leaderboardPanel, provider,
|
||||
durationConsumer);
|
||||
|
||||
+2
@@ -6,6 +6,8 @@
|
||||
<inherits name="com.sap.sse.gwt.CommonSharedResources" />
|
||||
|
||||
<source path='client'/>
|
||||
<source path='communication'/>
|
||||
<source path='theme'/>
|
||||
|
||||
</module>
|
||||
|
||||
+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;
|
||||
|
||||
-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);
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class RegattaCompetitorAnalyticsTabView extends SharedLeaderboardRegattaT
|
||||
}
|
||||
};
|
||||
if (regattaAnalyticsManager.getLeaderboardPanel() == null) {
|
||||
currentPresenter.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
currentPresenter.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ public class RegattaLeaderboardTabView extends SharedLeaderboardRegattaTabView<R
|
||||
|
||||
private void loadAvailableDetailTypes(final String leaderboardName, final AcceptsOneWidget contentArea,
|
||||
final Consumer<Iterable<DetailType>> callback) {
|
||||
currentPresenter.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
currentPresenter.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
|
||||
+19
-7
@@ -4,7 +4,9 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.MultiCompetitorLeaderboardChartSettings;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.MultiRaceLeaderboardSettings;
|
||||
@@ -12,6 +14,7 @@ import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
|
||||
import com.sap.sailing.gwt.ui.client.FlagImageResolver;
|
||||
import com.sap.sailing.gwt.ui.client.SailingClientFactory;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
|
||||
@@ -42,33 +45,32 @@ public class EventSeriesAnalyticsDataManager {
|
||||
private final CompetitorSelectionModel competitorSelectionProvider;
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final SailingClientFactory sailingCF;
|
||||
private final Timer timer;
|
||||
private final int MAX_COMPETITORS_IN_CHART = 30;
|
||||
private final FlagImageResolver flagImageResolver;
|
||||
|
||||
public EventSeriesAnalyticsDataManager(final SailingServiceAsync sailingService,
|
||||
public EventSeriesAnalyticsDataManager(final SailingClientFactory sailingCF,
|
||||
AsyncActionsExecutor asyncActionsExecutor, Timer timer, ErrorReporter errorReporter,
|
||||
FlagImageResolver flagImageResolver) {
|
||||
this.flagImageResolver = flagImageResolver;
|
||||
this.competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true);
|
||||
this.sailingService = sailingService;
|
||||
this.sailingCF = sailingCF;
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
this.timer = timer;
|
||||
this.errorReporter = errorReporter;
|
||||
this.overallLeaderboardPanel = null;
|
||||
this.multiCompetitorChart = null;
|
||||
}
|
||||
|
||||
public SailingServiceAsync getSailingService() {
|
||||
return sailingService;
|
||||
}
|
||||
|
||||
public MultiRaceLeaderboardPanel createMultiRaceOverallLeaderboardPanel(Component<?> parent, ComponentContext<?> context,
|
||||
final MultiRaceLeaderboardSettings leaderboardSettings,
|
||||
final String leaderboardGroupName, String leaderboardName, boolean showRaceDetails,
|
||||
boolean autoExpandLastRaceColumn, Iterable<DetailType> availableDetailTypes) {
|
||||
|
||||
|
||||
if(overallLeaderboardPanel == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
overallLeaderboardPanel = new MultiRaceLeaderboardPanel(parent, context, sailingService, asyncActionsExecutor,
|
||||
leaderboardSettings, true,
|
||||
competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter,
|
||||
@@ -84,7 +86,10 @@ public class EventSeriesAnalyticsDataManager {
|
||||
public MultiCompetitorLeaderboardChart createMultiCompetitorChart(Component<?> parent,
|
||||
ComponentContext<?> context, String leaderboardName,
|
||||
DetailType chartDetailType) {
|
||||
|
||||
if(multiCompetitorChart == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
|
||||
multiCompetitorChart = new MultiCompetitorLeaderboardChart(parent, context, sailingService,
|
||||
asyncActionsExecutor,
|
||||
leaderboardName, chartDetailType,
|
||||
@@ -99,6 +104,7 @@ public class EventSeriesAnalyticsDataManager {
|
||||
String preselectedLeaderboardName, String leaderboardGroupName,
|
||||
String metaLeaderboardName, boolean showRaceDetails, boolean autoExpandLastRaceColumn, Iterable<DetailType> availableDetailTypes) {
|
||||
if(multiLeaderboardPanel == null) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> metaLeaderboardName);
|
||||
multiLeaderboardPanel = new MultiLeaderboardProxyPanel(parent, context, sailingService, metaLeaderboardName,
|
||||
asyncActionsExecutor, timer, true /* isEmbedded */,
|
||||
preselectedLeaderboardName, errorReporter, StringMessages.INSTANCE,
|
||||
@@ -179,4 +185,10 @@ public class EventSeriesAnalyticsDataManager {
|
||||
public Timer getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
public void getAvailableDetailTypesForLeaderboard(String leaderboardName, RegattaAndRaceIdentifier raceOrNull,
|
||||
AsyncCallback<Iterable<DetailType>> asyncCallback) {
|
||||
SailingServiceAsync sailingService = sailingCF.getSailingService(()-> leaderboardName);
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName, raceOrNull, asyncCallback);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class SeriesActivity extends AbstractActivity implements SeriesView.Prese
|
||||
|
||||
if (this.ctx.getAnalyticsManager() == null) {
|
||||
ctx.withAnalyticsManager(new EventSeriesAnalyticsDataManager( //
|
||||
clientFactory.getSailingService(), //
|
||||
clientFactory, //
|
||||
asyncActionsExecutor, //
|
||||
new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds), //
|
||||
clientFactory.getErrorReporter(), flagImageResolver));
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ public class EventSeriesCompetitorAnalyticsTabView extends SharedLeaderboardEven
|
||||
}
|
||||
};
|
||||
if (eventSeriesAnalyticsManager.getLeaderboardPanel() == null) {
|
||||
eventSeriesAnalyticsManager.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
eventSeriesAnalyticsManager.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT
|
||||
final EventSeriesAnalyticsDataManager regattaAnalyticsManager = currentPresenter.getCtx()
|
||||
.getAnalyticsManager();
|
||||
|
||||
regattaAnalyticsManager.getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
regattaAnalyticsManager.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
|
||||
+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, null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
currentPresenter.getCtx().getAnalyticsManager().getAvailableDetailTypesForLeaderboard(leaderboardName, null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> result) {
|
||||
|
||||
+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
-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) {
|
||||
|
||||
+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);
|
||||
}
|
||||
+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;
|
||||
}
|
||||
}
|
||||
+42
-36
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.dto.AbstractLeaderboardDTO;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPerspectiveLifecycle;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardPerspectiveOwnSettings;
|
||||
@@ -40,12 +41,13 @@ import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class LeaderboardEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
public static final long DEFAULT_REFRESH_INTERVAL_MILLIS = 3000l;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(LeaderboardEntryPoint.class.getName());
|
||||
|
||||
private StringMessages stringmessages = StringMessages.INSTANCE;
|
||||
private UUID eventId;
|
||||
private String leaderboardName;
|
||||
private String leaderboardGroupName;
|
||||
private AbstractLeaderboardDTO leaderboardDTO;
|
||||
@@ -58,7 +60,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
leaderboardContextDefinition = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new LeaderboardContextDefinition());
|
||||
|
||||
final UUID eventId = leaderboardContextDefinition.getEventId();
|
||||
eventId = leaderboardContextDefinition.getEventId();
|
||||
|
||||
leaderboardName = leaderboardContextDefinition.getLeaderboardName();
|
||||
leaderboardGroupName = leaderboardContextDefinition.getLeaderboardGroupName();
|
||||
@@ -67,9 +69,8 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
if (eventId == null) {
|
||||
checkLeaderboardNameAndCreateUI(); // use null-initialized event field
|
||||
} else {
|
||||
// TODO it seems we do not really need the EventDTO. What's the intention of loading it? Should we
|
||||
// visualize some information in the header?
|
||||
sailingService.getEventById(eventId, /* withStatisticalData */false,
|
||||
// TODO it seems we do not really need the EventDTO. What's the intention of loading it? Should we visualize some information in the header?
|
||||
getSailingService().getEventById(eventId, /* withStatisticalData */false,
|
||||
new MarkedAsyncCallback<EventDTO>(new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -78,7 +79,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
@Override
|
||||
public void onSuccess(EventDTO result) {
|
||||
if (result != null) {
|
||||
if(result != null) {
|
||||
leaderboardDTO = result.getLeaderboardByName(leaderboardName);
|
||||
}
|
||||
checkLeaderboardNameAndCreateUI();
|
||||
@@ -89,27 +90,27 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkLeaderboardNameAndCreateUI() {
|
||||
if (leaderboardDTO == null) {
|
||||
sailingService.getLeaderboard(leaderboardName,
|
||||
new MarkedAsyncCallback<StrippedLeaderboardDTO>(new AsyncCallback<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public void onSuccess(StrippedLeaderboardDTO leaderboardDTO) {
|
||||
if (leaderboardDTO != null) {
|
||||
LeaderboardEntryPoint.this.leaderboardDTO = leaderboardDTO;
|
||||
Window.setTitle(leaderboardName);
|
||||
loadSettingsAndCreateUI();
|
||||
} else {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
if(leaderboardDTO == null) {
|
||||
getSailingService().getLeaderboard(leaderboardName,
|
||||
new MarkedAsyncCallback<StrippedLeaderboardDTO>(new AsyncCallback<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public void onSuccess(StrippedLeaderboardDTO leaderboardDTO) {
|
||||
if (leaderboardDTO != null) {
|
||||
LeaderboardEntryPoint.this.leaderboardDTO = leaderboardDTO;
|
||||
Window.setTitle(leaderboardName);
|
||||
loadSettingsAndCreateUI();
|
||||
} else {
|
||||
RootPanel.get().add(new Label(getStringMessages().noSuchLeaderboard()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: " + t.getMessage());
|
||||
}
|
||||
}));
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: " + t.getMessage());
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
loadSettingsAndCreateUI();
|
||||
}
|
||||
@@ -118,12 +119,12 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
private void loadSettingsAndCreateUI() {
|
||||
long delayBetweenAutoAdvancesInMilliseconds = DEFAULT_REFRESH_INTERVAL_MILLIS;
|
||||
final Timer timer = new Timer(PlayModes.Live, PlayStates.Paused, delayBetweenAutoAdvancesInMilliseconds);
|
||||
|
||||
|
||||
// make a single live request as the default but don't continue to play by default
|
||||
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory
|
||||
.createStoredSettingsLocatorForLeaderboard(leaderboardContextDefinition);
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
.createStoredSettingsLocatorForLeaderboard(leaderboardContextDefinition);
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -147,7 +148,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
final MetaLeaderboardViewer leaderboardViewer = new MetaLeaderboardViewer(
|
||||
null, context, rootComponentLifeCycle, defaultSettings,
|
||||
sailingService, new AsyncActionsExecutor(), timer, null,
|
||||
getSailingService(), new AsyncActionsExecutor(), timer, null,
|
||||
leaderboardGroupName, leaderboardName, LeaderboardEntryPoint.this,
|
||||
getStringMessages(), getActualChartDetailType(defaultSettings),
|
||||
result);
|
||||
@@ -174,7 +175,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
@Override
|
||||
public void onSuccess(
|
||||
PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings> defaultSettings) {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName,
|
||||
null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
@@ -189,7 +190,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
configureWithSettings(defaultSettings, timer);
|
||||
final MultiRaceLeaderboardViewer leaderboardViewer = new MultiRaceLeaderboardViewer(
|
||||
null, context, rootComponentLifeCycle,
|
||||
defaultSettings, sailingService,
|
||||
defaultSettings, getSailingService(),
|
||||
new AsyncActionsExecutor(), timer,
|
||||
leaderboardGroupName, leaderboardName,
|
||||
LeaderboardEntryPoint.this, getStringMessages(),
|
||||
@@ -212,25 +213,26 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private DetailType getActualChartDetailType(
|
||||
PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings> settings) {
|
||||
MultiCompetitorLeaderboardChartSettings chartSettings = settings
|
||||
.findSettingsByComponentId(MultiCompetitorLeaderboardChartLifecycle.ID);
|
||||
DetailType chartDetailType = chartSettings == null ? null : chartSettings.getDetailType();
|
||||
|
||||
|
||||
if (chartDetailType == DetailType.REGATTA_NET_POINTS_SUM) {
|
||||
return chartDetailType;
|
||||
}
|
||||
return MultiCompetitorLeaderboardChartSettings.getDefaultDetailType(leaderboardDTO.type.isMetaLeaderboard());
|
||||
}
|
||||
|
||||
|
||||
private void createUi(Widget leaderboardViewer,
|
||||
PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings> settings, Timer timer,
|
||||
LeaderboardContextDefinition leaderboardContextSettings) {
|
||||
LeaderboardPerspectiveOwnSettings ownSettings = settings.getPerspectiveOwnSettings();
|
||||
|
||||
|
||||
DockLayoutPanel mainPanel = new DockLayoutPanel(Unit.PX);
|
||||
RootLayoutPanel.get().add(mainPanel);
|
||||
if (!ownSettings.isEmbedded()) {
|
||||
@@ -258,11 +260,15 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
+ ");-o-transform-origin: 0 0;-webkit-transform: scale(" + zoomTo
|
||||
+ ");-webkit-transform-origin: 0 0;");
|
||||
}
|
||||
|
||||
|
||||
if (perspectiveOwnSettings.isLifePlay()) {
|
||||
timer.setPlayMode(PlayModes.Live); // the leaderboard, viewed via the entry point, goes "live" and "playing"
|
||||
// if an auto-refresh
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderboardName;
|
||||
}
|
||||
}
|
||||
+14
-7
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.common.security.Permission;
|
||||
import com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.leaderboardedit.LeaderboardEditContextDefinition;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint;
|
||||
@@ -29,22 +30,23 @@ import com.sap.sse.security.ui.authentication.generic.GenericAuthentication;
|
||||
import com.sap.sse.security.ui.authentication.generic.GenericAuthorizedContentDecorator;
|
||||
import com.sap.sse.security.ui.authentication.generic.sapheader.SAPHeaderWithAuthentication;
|
||||
|
||||
public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
public class LeaderboardEditPage extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
private static final Logger logger = Logger.getLogger(LeaderboardEntryPoint.class.getName());
|
||||
private String leaderboardName;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
|
||||
sailingService.getLeaderboardNames(new MarkedAsyncCallback<List<String>>(
|
||||
final LeaderboardEditContextDefinition settings = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new LeaderboardEditContextDefinition());
|
||||
leaderboardName = settings.getLeaderboardName();
|
||||
getSailingService().getLeaderboardNames(new MarkedAsyncCallback<List<String>>(
|
||||
new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onSuccess(List<String> leaderboardNames) {
|
||||
final LeaderboardEditContextDefinition settings = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new LeaderboardEditContextDefinition());
|
||||
final String leaderboardName = settings.getLeaderboardName();
|
||||
if (leaderboardNames.contains(leaderboardName)) {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(leaderboardName, null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(leaderboardName, null, new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -60,7 +62,7 @@ public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
authorizedContentDecorator.setContentWidgetFactory(new WidgetFactory() {
|
||||
@Override
|
||||
public Widget get() {
|
||||
EditableLeaderboardPanel leaderboardPanel = new EditableLeaderboardPanel(sailingService, new AsyncActionsExecutor(), leaderboardName, null,
|
||||
EditableLeaderboardPanel leaderboardPanel = new EditableLeaderboardPanel(getSailingService(), new AsyncActionsExecutor(), leaderboardName, null,
|
||||
LeaderboardEditPage.this, getStringMessages(), userAgent, result);
|
||||
leaderboardPanel.ensureDebugId("EditableLeaderboardPanel");
|
||||
return leaderboardPanel;
|
||||
@@ -91,4 +93,9 @@ public class LeaderboardEditPage extends AbstractSailingEntryPoint {
|
||||
header.getElement().getStyle().setWidth(100, Unit.PCT);
|
||||
return header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderboardName;
|
||||
}
|
||||
}
|
||||
+13
-6
@@ -18,6 +18,7 @@ import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.dto.PairingListDTO;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.ui.adminconsole.PairingListPreviewDialog;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -25,19 +26,21 @@ import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
|
||||
public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class PairingListEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
|
||||
private PairingListContextDefinition pairingListContextDefinition;
|
||||
|
||||
private StringMessages stringMessages = StringMessages.INSTANCE;
|
||||
private StrippedLeaderboardDTO strippedLeaderboardDTO;
|
||||
|
||||
private String leaderboardName;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
pairingListContextDefinition = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new PairingListContextDefinition());
|
||||
this.sailingService.getLeaderboard(pairingListContextDefinition.getLeaderboardName(),
|
||||
leaderboardName = pairingListContextDefinition.getLeaderboardName();
|
||||
getSailingService().getLeaderboard(leaderboardName,
|
||||
new AsyncCallback<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -68,12 +71,12 @@ public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
contentPanel.getElement().getStyle().setProperty("marginTop", "15px");
|
||||
contentPanel.getElement().getStyle().setProperty("marginBottom", "15px");
|
||||
scrollPanel.add(contentPanel);
|
||||
sailingService.getPairingListFromRaceLogs(pairingListContextDefinition.getLeaderboardName(),
|
||||
getSailingService().getPairingListFromRaceLogs(pairingListContextDefinition.getLeaderboardName(),
|
||||
new AsyncCallback<PairingListDTO>() {
|
||||
@Override
|
||||
public void onSuccess(PairingListDTO result) {
|
||||
if (strippedLeaderboardDTO != null) {
|
||||
sailingService.getRaceDisplayNamesFromLeaderboard(strippedLeaderboardDTO.getName(),
|
||||
getSailingService().getRaceDisplayNamesFromLeaderboard(strippedLeaderboardDTO.getName(),
|
||||
result.getRaceColumnNames(), new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
@@ -126,7 +129,7 @@ public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
pairingListPanel.getElement().getStyle().setProperty("marginTop", "15px");
|
||||
return pairingListPanel;
|
||||
}
|
||||
|
||||
|
||||
private native void printPairingListGrid(String pageHTMLContent) /*-{
|
||||
var frameID = '__gwt_historyFrame';
|
||||
var frame = $doc.getElementById(frameID);
|
||||
@@ -167,4 +170,8 @@ public class PairingListEntryPoint extends AbstractSailingEntryPoint {
|
||||
}, 100);
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderboardName;
|
||||
}
|
||||
}
|
||||
+12
-6
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.common.dto.BoatDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceBoardPerspectiveOwnSettings;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractSailingEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProvider;
|
||||
@@ -62,7 +63,7 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.authentication.generic.sapheader.SAPHeaderWithAuthentication;
|
||||
|
||||
public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
private static final String PARAM_REGATTA_LIKE_NAME = "regattaLikeName";
|
||||
private static final String PARAM_RACE_COLUMN_NAME = "raceColumnName";
|
||||
private static final String PARAM_FLEET_NAME = "fleetName";
|
||||
@@ -122,13 +123,13 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
defaultRaceMapSettings.isShowDouglasPeuckerPoints(), true,
|
||||
defaultRaceMapSettings.getStartCountDownFontSizeScaling());
|
||||
|
||||
sailingService.getRaceIdentifier(regattaLikeName, raceColumnName, fleetName, new AsyncCallback<RegattaAndRaceIdentifier>() {
|
||||
getSailingService().getRaceIdentifier(regattaLikeName, raceColumnName, fleetName, new AsyncCallback<RegattaAndRaceIdentifier>() {
|
||||
@Override
|
||||
public void onSuccess(final RegattaAndRaceIdentifier selectedRaceIdentifier) {
|
||||
if (selectedRaceIdentifier == null) {
|
||||
createErrorPage(getStringMessages().couldNotObtainRace(regattaLikeName, raceColumnName, fleetName, /* technicalErrorMessage */ ""));
|
||||
} else {
|
||||
sailingService.getCompetitorBoats(selectedRaceIdentifier, new AsyncCallback<Map<CompetitorDTO, BoatDTO>>() {
|
||||
getSailingService().getCompetitorBoats(selectedRaceIdentifier, new AsyncCallback<Map<CompetitorDTO, BoatDTO>>() {
|
||||
@Override
|
||||
public void onSuccess(Map<CompetitorDTO, BoatDTO> result) {
|
||||
createEmbeddedMap(selectedRaceIdentifier, result, raceboardPerspectiveSettings, raceMapSettings,
|
||||
@@ -187,7 +188,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
return true;
|
||||
}
|
||||
};
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, asyncActionsExecutor, /* errorReporter */ this,
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(getSailingService(), asyncActionsExecutor, /* errorReporter */ this,
|
||||
Collections.singleton(selectedRaceIdentifier), 30000l /* requestInterval*/);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(new RaceTimesInfoProviderListener() {
|
||||
@Override
|
||||
@@ -208,7 +209,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
competitorSelection = createEmptyFilterCompetitorModel(colorProvider, competitorsAndBoats); // show no competitors
|
||||
}
|
||||
final RaceMap raceMap = new RaceMap(null, null, new RaceMapLifecycle(getStringMessages()), raceMapSettings,
|
||||
sailingService, asyncActionsExecutor, /* errorReporter */ EmbeddedMapAndWindChartEntryPoint.this, timer,
|
||||
getSailingService(), asyncActionsExecutor, /* errorReporter */ EmbeddedMapAndWindChartEntryPoint.this, timer,
|
||||
competitorSelection, new RaceCompetitorSet(competitorSelection), getStringMessages(), selectedRaceIdentifier,
|
||||
raceMapResources, /* showHeaderPanel */ false, new DefaultQuickRanksDTOProvider()) {
|
||||
@Override
|
||||
@@ -219,7 +220,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
};
|
||||
final WindChart windChart;
|
||||
if (raceboardPerspectiveSettings.isShowWindChart()) {
|
||||
windChart = new WindChart(null, null, new WindChartLifecycle(getStringMessages()), sailingService,
|
||||
windChart = new WindChart(null, null, new WindChartLifecycle(getStringMessages()), getSailingService(),
|
||||
selectedRaceIdentifier, timer,
|
||||
timeRangeWithZoomProvider, new WindChartSettings(), getStringMessages(),
|
||||
asyncActionsExecutor, /* errorReporter */
|
||||
@@ -254,4 +255,9 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
p.insert(raceMap.getEntryWidget(), raceMap, Direction.CENTER, 400);
|
||||
p.addStyleName("dockLayoutPanel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return regattaLikeName;
|
||||
}
|
||||
}
|
||||
+26
-12
@@ -14,6 +14,7 @@ import com.google.gwt.user.client.ui.RootLayoutPanel;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.common.authentication.FixedSailingAuthentication;
|
||||
import com.sap.sailing.gwt.common.authentication.SAPSailingHeaderWithAuthentication;
|
||||
import com.sap.sailing.gwt.common.communication.routing.ProvidesLeaderboardRouting;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceBoardPerspectiveOwnSettings;
|
||||
import com.sap.sailing.gwt.settings.client.raceboard.RaceboardContextDefinition;
|
||||
import com.sap.sailing.gwt.settings.client.utils.StoredSettingsLocationFactory;
|
||||
@@ -38,7 +39,7 @@ import com.sap.sse.security.ui.authentication.generic.sapheader.SAPHeaderWithAut
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StoredSettingsLocation;
|
||||
|
||||
public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
public class RaceBoardEntryPoint extends AbstractSailingEntryPoint implements ProvidesLeaderboardRouting {
|
||||
private RaceWithCompetitorsAndBoatsDTO selectedRace;
|
||||
|
||||
/**
|
||||
@@ -48,10 +49,13 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
private RaceboardContextDefinition raceboardContextDefinition;
|
||||
|
||||
private String leaderBoardName;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) mediaService, RemoteServiceMappingConstants.mediaServiceRemotePath);
|
||||
EntryPointHelper.registerASyncService((ServiceDefTarget) mediaService,
|
||||
RemoteServiceMappingConstants.mediaServiceRemotePath);
|
||||
raceboardContextDefinition = new SettingsToUrlSerializer()
|
||||
.deserializeFromCurrentLocation(new RaceboardContextDefinition());
|
||||
final RaceBoardModes finalMode;
|
||||
@@ -61,12 +65,16 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
finalMode = null;
|
||||
}
|
||||
if (raceboardContextDefinition.getRegattaName() == null || raceboardContextDefinition.getRegattaName().isEmpty()
|
||||
|| raceboardContextDefinition.getRaceName() == null || raceboardContextDefinition.getRaceName().isEmpty()
|
||||
|| raceboardContextDefinition.getRaceName() == null
|
||||
|| raceboardContextDefinition.getRaceName().isEmpty()
|
||||
|| raceboardContextDefinition.getLeaderboardName() == null
|
||||
|| raceboardContextDefinition.getLeaderboardName().isEmpty()) {
|
||||
createErrorPage(getStringMessages().requiresRegattaRaceAndLeaderboard());
|
||||
return;
|
||||
}
|
||||
|
||||
leaderBoardName = raceboardContextDefinition.getLeaderboardName();
|
||||
|
||||
AsyncCallback<RaceboardDataDTO> asyncCallback = new AsyncCallback<RaceboardDataDTO>() {
|
||||
@Override
|
||||
public void onSuccess(RaceboardDataDTO raceboardData) {
|
||||
@@ -93,17 +101,18 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
}
|
||||
if (raceboardData.getRace() == null) {
|
||||
createErrorPage(getStringMessages().couldNotFindRaceInRegatta(raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getRegattaName()));
|
||||
createErrorPage(getStringMessages().couldNotFindRaceInRegatta(
|
||||
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getRegattaName()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final boolean showChartMarkEditMediaButtonsAndVideo = !DeviceDetector.isMobile();
|
||||
final StoredSettingsLocation storageDefinition = StoredSettingsLocationFactory
|
||||
.createStoredSettingsLocatorForRaceBoard(raceboardContextDefinition,
|
||||
finalMode != null ? finalMode.name() : null);
|
||||
// TODO bug2822: also determine regatta's boat change parameter and parameterize Leaderboard settings
|
||||
// --> show boat info column yes/no?
|
||||
sailingService.determineDetailTypesForCompetitorChart(
|
||||
getSailingService().determineDetailTypesForCompetitorChart(
|
||||
raceboardContextDefinition.getLeaderboardGroupName(),
|
||||
raceboardData.getRace().getRaceIdentifier(), new AsyncCallback<Iterable<DetailType>>() {
|
||||
|
||||
@@ -114,7 +123,7 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Iterable<DetailType> chartAllowedTypes) {
|
||||
sailingService.getAvailableDetailTypesForLeaderboard(
|
||||
getSailingService().getAvailableDetailTypesForLeaderboard(
|
||||
raceboardContextDefinition.getLeaderboardName(),
|
||||
raceboardData.getRace().getRaceIdentifier(), new AsyncCallback<Iterable<DetailType>>() {
|
||||
@Override
|
||||
@@ -152,13 +161,13 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
reportError("Error trying to create the raceboard: " + caught.getMessage());
|
||||
}
|
||||
};
|
||||
sailingService.getRaceboardData(raceboardContextDefinition.getRegattaName(),
|
||||
getSailingService().getRaceboardData(raceboardContextDefinition.getRegattaName(),
|
||||
raceboardContextDefinition.getRaceName(), raceboardContextDefinition.getLeaderboardName(),
|
||||
raceboardContextDefinition.getLeaderboardGroupName(), raceboardContextDefinition.getEventId(),
|
||||
asyncCallback);
|
||||
@@ -185,10 +194,10 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
selectedRace = raceboardData.getRace();
|
||||
Window.setTitle(selectedRace.getName());
|
||||
AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, asyncActionsExecutor, this,
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(getSailingService(), asyncActionsExecutor, this,
|
||||
Collections.singletonList(selectedRace.getRaceIdentifier()), 5000l /* requestInterval*/);
|
||||
RaceBoardPanel raceBoardPerspective = new RaceBoardPanel(parent, context, raceLifeCycle, settings,
|
||||
sailingService, mediaService, getUserService(), asyncActionsExecutor,
|
||||
getSailingService(), mediaService, getUserService(), asyncActionsExecutor,
|
||||
raceboardData.getCompetitorAndTheirBoats(), timer, selectedRace.getRaceIdentifier(),
|
||||
raceboardContextDefinition.getLeaderboardName(), raceboardContextDefinition.getLeaderboardGroupName(),
|
||||
raceboardContextDefinition.getEventId(), RaceBoardEntryPoint.this, getStringMessages(), userAgent,
|
||||
@@ -196,4 +205,9 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
RootLayoutPanel.get().add(raceBoardPerspective.getEntryWidget());
|
||||
return raceBoardPerspective;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLeaderboardName() {
|
||||
return leaderBoardName;
|
||||
}
|
||||
}
|
||||
+37
@@ -53,6 +53,10 @@ import java.util.stream.StreamSupport;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
@@ -278,6 +282,7 @@ import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||
import com.sap.sailing.domain.common.security.Permission;
|
||||
import com.sap.sailing.domain.common.security.Permission.Mode;
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
@@ -318,6 +323,7 @@ import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||
import com.sap.sailing.domain.sharding.ShardingContext;
|
||||
import com.sap.sailing.domain.swisstimingadapter.StartList;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapter;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapterFactory;
|
||||
@@ -2539,6 +2545,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void checkLeaderboardRouting(String leaderboardName) {
|
||||
final String currentRequestUrl = getThreadLocalRequest().getRequestURL().toString();
|
||||
if (!currentRequestUrl.contains("/leaderboard/")) {
|
||||
logger.log(Level.WARNING, "Leaderboard routing stacktrace", new RuntimeException("Request without leaderboard routing information"));
|
||||
} else {
|
||||
if (currentRequestUrl.contains(leaderboardName)) {
|
||||
logger.info("leaderboard access matches leaderboard url");
|
||||
} else {
|
||||
logger.info("leaderboard access to " + leaderboardName + " does not match request url " + currentRequestUrl);
|
||||
logger.log(Level.SEVERE, "Leaderboard routing stacktrace", new RuntimeException("Request without leaderboard routing information"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link LeaderboardDTO} for <code>leaderboard</code> and fills in the name, race master data
|
||||
@@ -2549,6 +2569,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
* If <code>withGeoLocationData</code> is <code>true</code> the geographical location of all races will be determined.
|
||||
*/
|
||||
private StrippedLeaderboardDTO createStrippedLeaderboardDTO(Leaderboard leaderboard, boolean withGeoLocationData, boolean withStatisticalData) {
|
||||
checkLeaderboardRouting(leaderboard.getName());
|
||||
|
||||
StrippedLeaderboardDTO leaderboardDTO = new StrippedLeaderboardDTO(convertToBoatClassDTO(leaderboard.getBoatClass()));
|
||||
TimePoint startOfLatestRace = null;
|
||||
Long delayToLiveInMillisForLatestRace = null;
|
||||
@@ -7851,4 +7873,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
||||
ShardingType identifiedShardingType = null;
|
||||
try {
|
||||
if (req instanceof HttpServletRequest) {
|
||||
identifiedShardingType = ShardingContext.identifyAndSetShardingConstraint(((HttpServletRequest) req).getPathInfo());
|
||||
}
|
||||
super.service(req, res);
|
||||
} finally {
|
||||
if (identifiedShardingType != null) {
|
||||
ShardingContext.clearShardingConstraint(identifiedShardingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -38,7 +38,7 @@ public class SpectatorEntryPoint extends AbstractSailingEntryPoint implements Re
|
||||
} else {
|
||||
groupName = groupParamValue;
|
||||
Window.setTitle(groupName);
|
||||
sailingService.getLeaderboardGroupByName(groupName, false /*withGeoLocationData*/, new AsyncCallback<LeaderboardGroupDTO>() {
|
||||
getSailingService().getLeaderboardGroupByName(groupName, false /*withGeoLocationData*/, new AsyncCallback<LeaderboardGroupDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError(getStringMessages().noLeaderboardGroupWithNameFound(groupName));
|
||||
@@ -58,11 +58,11 @@ public class SpectatorEntryPoint extends AbstractSailingEntryPoint implements Re
|
||||
// DON'T DELETE -> the EventOverviewPanel will replace the LeaderboardGroupOverviewPanel later on
|
||||
// EventOverviewPanel eventOverviewPanel = new EventOverviewPanel(sailingService, this, stringMessages, showRaceDetails);
|
||||
// groupOverviewPanel.add( eventOverviewPanel);
|
||||
LeaderboardGroupOverviewPanel leaderboardGroupOverviewPanel = new LeaderboardGroupOverviewPanel(sailingService, this, getStringMessages(), settings.isShowRaceDetails());
|
||||
LeaderboardGroupOverviewPanel leaderboardGroupOverviewPanel = new LeaderboardGroupOverviewPanel(getSailingService(), this, getStringMessages(), settings.isShowRaceDetails());
|
||||
groupOverviewPanel.add(leaderboardGroupOverviewPanel);
|
||||
rootPanel.add(groupOverviewPanel);
|
||||
} else {
|
||||
LeaderboardGroupPanel groupPanel = new LeaderboardGroupPanel(sailingService, getStringMessages(), this,
|
||||
LeaderboardGroupPanel groupPanel = new LeaderboardGroupPanel(getSailingService(), getStringMessages(), this,
|
||||
groupName, settings.getViewMode(), embedded, settings.isShowRaceDetails(), settings.isCanReplayDuringLiveRaces(),
|
||||
settings.isShowMapControls());
|
||||
groupAndFeedbackPanel.add(groupPanel);
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.sap.sailing.server.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.sharding.ShardingType;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class ShardingLeaderBoardEncodingTest {
|
||||
@Test
|
||||
public void testEncoding() {
|
||||
Assert.assertEquals("/leaderboard/pureascistring", ShardingType.LEADERBOARDNAME.encodeIfNeeded("pureascistring"));
|
||||
Assert.assertEquals("/leaderboard/unpure_asci_string", ShardingType.LEADERBOARDNAME.encodeIfNeeded("unpure asci string"));
|
||||
Assert.assertEquals("/leaderboard/c_dille", ShardingType.LEADERBOARDNAME.encodeIfNeeded("cédille"));
|
||||
Assert.assertEquals("/leaderboard/Hello_World", ShardingType.LEADERBOARDNAME.encodeIfNeeded("Hello+World"));
|
||||
Assert.assertEquals("/leaderboard/Hello_World_", ShardingType.LEADERBOARDNAME.encodeIfNeeded("Hello(World)"));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,17 @@
|
||||
This can be done from the adminconsole->tracked races->audio & videos tab</li>
|
||||
<li>In raceboard when you edit a video you do not need to explicitly press "Preview" before saving anymore.
|
||||
Saving now implicitly applies the changes.</li>
|
||||
<li>The URLs of our GWT services are extended to include a leaderboard name if a call is context sensitive to a specific leaderboard.
|
||||
This does not affect the functionality of any service but allows us to setup load balancing with leaderboard specific routing.
|
||||
The leaderboard names put into the URL are cleaned: Any character that isn't a letter or digit is replaced with an underscore character.
|
||||
Currently, the following leaderboard specific URLs are used:
|
||||
<ul>
|
||||
<li>/gwt/service/sailing/leaderboard/[CLEANED-LEADERBOARD-NAME]</li>
|
||||
<li>/gwt/service/dispatch/leaderboard/[CLEANED-LEADERBOARD-NAME]</li>
|
||||
</ul>
|
||||
Be aware that request without leaderboard suffix may be sent from pages that do not show leaderboard specific contents.
|
||||
Due to this it is required to define a fallback rule for any unqualified request.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="articleSubheadline">May 2018</h2>
|
||||
|
||||
@@ -57,6 +57,7 @@ Export-Package: com.google.gwt.user.client.rpc.core.java.util,
|
||||
com.sap.sse.gwt.dispatch.client.system,
|
||||
com.sap.sse.gwt.dispatch.client.system.batching,
|
||||
com.sap.sse.gwt.dispatch.client.system.caching,
|
||||
com.sap.sse.gwt.dispatch.client.system.routing,
|
||||
com.sap.sse.gwt.dispatch.client.transport.gwtrpc,
|
||||
com.sap.sse.gwt.dispatch.servlets,
|
||||
com.sap.sse.gwt.dispatch.shared.caching,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.sap.sse.gwt.client;
|
||||
|
||||
import com.sap.sse.gwt.dispatch.client.system.DispatchSystemDefaultImpl;
|
||||
|
||||
/**
|
||||
* Interface used to append a routing suffix to target url
|
||||
* in GWT RPC service instances and in {@link DispatchSystemDefaultImpl}
|
||||
*/
|
||||
public interface ServiceRoutingProvider {
|
||||
|
||||
String routingSuffixPath();
|
||||
}
|
||||
+39
-6
@@ -1,11 +1,14 @@
|
||||
package com.sap.sse.gwt.dispatch.client.system;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sse.gwt.client.ServiceRoutingProvider;
|
||||
import com.sap.sse.gwt.dispatch.client.system.batching.AutomaticBatchingDispatch;
|
||||
import com.sap.sse.gwt.dispatch.client.system.caching.CachingDispatch;
|
||||
import com.sap.sse.gwt.dispatch.client.transport.DefaultTransport;
|
||||
@@ -27,8 +30,11 @@ public abstract class DispatchSystemDefaultImpl<CTX extends DispatchContext> imp
|
||||
ProvidesServerTime {
|
||||
private final Logger LOG = Logger.getLogger(DispatchSystemDefaultImpl.class.getName());
|
||||
private final DefaultTransport<CTX> simpleDispatch;
|
||||
private final DispatchSystemAsync<CTX> dispatch;
|
||||
|
||||
private final DispatchSystemAsync<CTX> defaultDispatch;
|
||||
private final Map<String,DispatchSystemAsync<CTX>> routingRegistry = new HashMap<>();
|
||||
private final boolean processResultsScheduled;
|
||||
private final String dispatchRPCPath;
|
||||
|
||||
public DispatchSystemDefaultImpl(String dispatchRPCPath) {
|
||||
this(dispatchRPCPath, false);
|
||||
}
|
||||
@@ -43,10 +49,25 @@ public abstract class DispatchSystemDefaultImpl<CTX extends DispatchContext> imp
|
||||
* use a {@link Scheduler} to process the results
|
||||
*/
|
||||
public DispatchSystemDefaultImpl(String dispatchRPCPath, boolean processResultsScheduled) {
|
||||
this.dispatchRPCPath = dispatchRPCPath;
|
||||
this.processResultsScheduled = processResultsScheduled;
|
||||
simpleDispatch = new DefaultTransport<CTX>(dispatchRPCPath);
|
||||
dispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(
|
||||
simpleDispatch, processResultsScheduled));
|
||||
LOG.finest("Started dispatch system for " + dispatchRPCPath);
|
||||
defaultDispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(simpleDispatch, processResultsScheduled));
|
||||
LOG.finest("Started default dispatch system for " + dispatchRPCPath);
|
||||
}
|
||||
|
||||
private DispatchSystemAsync<CTX> createDispatchFor(String routing) {
|
||||
final StringBuilder destinationUrlBuilder = new StringBuilder(dispatchRPCPath);
|
||||
if (routing != null && !routing.isEmpty()) {
|
||||
if (!dispatchRPCPath.endsWith("/")) {
|
||||
destinationUrlBuilder.append("/");
|
||||
}
|
||||
destinationUrlBuilder.append(routing.startsWith("/") ? routing.substring(1) : routing);
|
||||
}
|
||||
DefaultTransport<CTX> transport = new DefaultTransport<CTX>(destinationUrlBuilder.toString());
|
||||
DispatchSystemAsync<CTX> dispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(
|
||||
transport, processResultsScheduled));
|
||||
return dispatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,7 +87,19 @@ public abstract class DispatchSystemDefaultImpl<CTX extends DispatchContext> imp
|
||||
callback.onSuccess(result);
|
||||
}
|
||||
};
|
||||
dispatch.execute(action, wrappedCallback);
|
||||
final DispatchSystemAsync<CTX> dispatchToUse;
|
||||
if (action instanceof ServiceRoutingProvider) {
|
||||
ServiceRoutingProvider providesDispatchRoutingKey = (ServiceRoutingProvider) action;
|
||||
String routingPath = providesDispatchRoutingKey.routingSuffixPath();
|
||||
|
||||
dispatchToUse = routingRegistry.computeIfAbsent(routingPath, this::createDispatchFor);
|
||||
|
||||
LOG.fine("Using routed dispatch for path "+ routingPath);
|
||||
} else {
|
||||
LOG.fine("Using default dispatch for "+ action.getClass().getName());
|
||||
dispatchToUse = defaultDispatch;
|
||||
}
|
||||
dispatchToUse.execute(action, wrappedCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in new issue
Block a user