first shot at bug 758 to support non-integer scores; UI formatting not taken care of yet

This commit is contained in:
Axel Uhl committed 2012-07-19 22:51:56 +02:00
1 parent a3c7a19616
commit c1e5247c99
30 files changed
+170 -187

No files matched your search

@@ -32,16 +32,16 @@ import com.sap.sailing.domain.tracking.TrackedRace;
*/
public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorrections {
private static final long serialVersionUID = 8824782847677232275L;
private final Map<String, Integer> carriedPointsByCompetitorName;
private final Map<String, Double> carriedPointsByCompetitorName;
private final Map<String, Map<RaceColumn, MaxPointsReason>> maxPointsReasonsByCompetitorName;
private final Map<String, Map<RaceColumn, Integer>> correctedScoresByCompetitorName;
private final Map<String, Map<RaceColumn, Double>> correctedScoresByCompetitorName;
private final Map<String, String> displayNamesByCompetitorName;
private final Leaderboard leaderboard;
public DelayedLeaderboardCorrectionsImpl(Leaderboard leaderboard) {
carriedPointsByCompetitorName = new HashMap<String, Integer>();
carriedPointsByCompetitorName = new HashMap<String, Double>();
maxPointsReasonsByCompetitorName = new HashMap<String, Map<RaceColumn,MaxPointsReason>>();
correctedScoresByCompetitorName = new HashMap<String, Map<RaceColumn,Integer>>();
correctedScoresByCompetitorName = new HashMap<String, Map<RaceColumn, Double>>();
displayNamesByCompetitorName = new HashMap<String, String>();
this.leaderboard = leaderboard;
leaderboard.addRaceColumnListener(this);
@@ -61,7 +61,7 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
}
@Override
public void setCarriedPoints(String competitorName, int carriedPoints) {
public void setCarriedPoints(String competitorName, double carriedPoints) {
assertNoTrackedRaceAssociatedYet();
carriedPointsByCompetitorName.put(competitorName, carriedPoints);
}
@@ -78,11 +78,11 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
}
@Override
public void correctScore(String competitorName, RaceColumn raceColumn, int correctedScore) {
public void correctScore(String competitorName, RaceColumn raceColumn, double correctedScore) {
assertNoTrackedRaceAssociatedYet();
Map<RaceColumn, Integer> map = correctedScoresByCompetitorName.get(competitorName);
Map<RaceColumn, Double> map = correctedScoresByCompetitorName.get(competitorName);
if (map == null) {
map = new HashMap<RaceColumn, Integer>();
map = new HashMap<RaceColumn, Double>();
correctedScoresByCompetitorName.put(competitorName, map);
}
map.put(raceColumn, correctedScore);
@@ -101,8 +101,8 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
for (Competitor competitor : race.getRace().getCompetitors()) {
competitorsByName.put(competitor.getName(), competitor);
}
for (Iterator<Map.Entry<String, Integer>> carryEntryIter = carriedPointsByCompetitorName.entrySet().iterator(); carryEntryIter.hasNext(); ) {
Map.Entry<String, Integer> carryEntry = carryEntryIter.next();
for (Iterator<Map.Entry<String, Double>> carryEntryIter = carriedPointsByCompetitorName.entrySet().iterator(); carryEntryIter.hasNext(); ) {
Map.Entry<String, Double> carryEntry = carryEntryIter.next();
if (competitorsByName.containsKey(carryEntry.getKey())) {
leaderboard.setCarriedPoints(competitorsByName.get(carryEntry.getKey()), carryEntry.getValue());
carryEntryIter.remove();
@@ -119,11 +119,11 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
maxPointsReasonsEntryIter.remove();
}
}
for (Iterator<java.util.Map.Entry<String, Map<RaceColumn, Integer>>> correctedScoresEntryIter =
for (Iterator<java.util.Map.Entry<String, Map<RaceColumn, Double>>> correctedScoresEntryIter =
correctedScoresByCompetitorName.entrySet().iterator(); correctedScoresEntryIter.hasNext();) {
java.util.Map.Entry<String, Map<RaceColumn, Integer>> correctedScoresEntries = correctedScoresEntryIter.next();
java.util.Map.Entry<String, Map<RaceColumn, Double>> correctedScoresEntries = correctedScoresEntryIter.next();
if (competitorsByName.containsKey(correctedScoresEntries.getKey())) {
for (java.util.Map.Entry<RaceColumn, Integer> correctedScoreEntry : correctedScoresEntries.getValue().entrySet()) {
for (java.util.Map.Entry<RaceColumn, Double> correctedScoreEntry : correctedScoresEntries.getValue().entrySet()) {
leaderboard.getScoreCorrection().correctScore(competitorsByName.get(correctedScoresEntries.getKey()),
correctedScoreEntry.getKey(), correctedScoreEntry.getValue());
}
@@ -266,7 +266,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
DBObject carriedPoints = (DBObject) dbLeaderboard.get(FieldNames.LEADERBOARD_CARRIED_POINTS.name());
if (carriedPoints != null) {
for (String competitorName : carriedPoints.keySet()) {
Integer carriedPointsForCompetitor = (Integer) carriedPoints.get(competitorName);
Double carriedPointsForCompetitor = (Double) carriedPoints.get(competitorName);
if (carriedPointsForCompetitor != null) {
correctionsToUpdate.setCarriedPoints(MongoUtils.unescapeDollarAndDot(competitorName), carriedPointsForCompetitor);
}
@@ -284,7 +284,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
.get(FieldNames.LEADERBOARD_SCORE_CORRECTION_MAX_POINTS_REASON.name())));
}
if (dbScoreCorrectionForCompetitorInRace.containsField(FieldNames.LEADERBOARD_CORRECTED_SCORE.name())) {
correctionsToUpdate.correctScore(MongoUtils.unescapeDollarAndDot(competitorName), raceColumn, (Integer) dbScoreCorrectionForCompetitorInRace
correctionsToUpdate.correctScore(MongoUtils.unescapeDollarAndDot(competitorName), raceColumn, (Double) dbScoreCorrectionForCompetitorInRace
.get(FieldNames.LEADERBOARD_CORRECTED_SCORE.name()));
}
}
@@ -205,7 +205,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
dbCorrectionForCompetitor.put(FieldNames.LEADERBOARD_SCORE_CORRECTION_MAX_POINTS_REASON.name(),
maxPointsReason.name());
}
Integer explicitScoreCorrection = scoreCorrection
Double explicitScoreCorrection = scoreCorrection
.getExplicitScoreCorrection(competitor, raceColumn);
if (explicitScoreCorrection != null) {
dbCorrectionForCompetitor.put(FieldNames.LEADERBOARD_CORRECTED_SCORE.name(),
@@ -43,24 +43,24 @@ public class LeaderboardForKielWeekTest extends OnlineTracTracBasedTest {
loadRace("357c700a-9d9a-11e0-85be-406186cbf87c"); // 505 Race 2
Competitor hasso = getCompetitorByName("Dr.Plattner");
RaceColumn column = leaderboard.addRace(getTrackedRace(), "Test Race 1", /* medalRace */ false, defaultFleet);
assertEquals(21, leaderboard.getTotalPoints(hasso, now));
assertEquals(21, leaderboard.getTotalPoints(hasso, now), 0.000000001);
Pair<Competitor, RaceColumn> key = new Pair<Competitor, RaceColumn>(hasso, column);
assertEquals(21, leaderboard.getContent(now).get(key).getTotalPoints());
assertEquals(21, leaderboard.getEntry(hasso, column, now).getTotalPoints());
assertEquals(21, leaderboard.getContent(now).get(key).getTotalPoints(), 0.000000001);
assertEquals(21, leaderboard.getEntry(hasso, column, now).getTotalPoints(), 0.000000001);
loadRace("e876c3a0-9da8-11e0-85be-406186cbf87c"); // 505 Race 3
column = leaderboard.addRace(getTrackedRace(), "Test Race 2", /* medalRace */ false, defaultFleet);
key = new Pair<Competitor, RaceColumn>(hasso, column);
// In Race 3, Hasso ranked 31st
assertEquals(52, leaderboard.getTotalPoints(hasso, now));
assertEquals(31, leaderboard.getContent(now).get(key).getTotalPoints());
assertEquals(31, leaderboard.getEntry(hasso, column, now).getTotalPoints());
assertEquals(52, leaderboard.getTotalPoints(hasso, now), 0.000000001);
assertEquals(31, leaderboard.getContent(now).get(key).getTotalPoints(), 0.000000001);
assertEquals(31, leaderboard.getEntry(hasso, column, now).getTotalPoints(), 0.000000001);
loadRace("7c666e50-9dde-11e0-85be-406186cbf87c"); // 505 Race 4
column = leaderboard.addRace(getTrackedRace(), "Test Race 3", /* medalRace */ false, defaultFleet);
key = new Pair<Competitor, RaceColumn>(hasso, column);
// now the second race is discarded because Hasso ranked worst compared to the other two; in race 4 he ranked 11th
assertEquals(32, leaderboard.getTotalPoints(hasso, now));
assertEquals(11, leaderboard.getContent(now).get(key).getTotalPoints());
assertEquals(11, leaderboard.getEntry(hasso, column, now).getTotalPoints());
assertEquals(32, leaderboard.getTotalPoints(hasso, now), 0.000000001);
assertEquals(11, leaderboard.getContent(now).get(key).getTotalPoints(), 0.000000001);
assertEquals(11, leaderboard.getEntry(hasso, column, now).getTotalPoints(), 0.000000001);
}
private void loadRace(String raceId) throws MalformedURLException, IOException, InterruptedException,
@@ -126,9 +126,9 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
scoreCorrection.setMaxPointsReason(competitor, bestScoringRaceColumn, MaxPointsReason.DSQ);
// assert that best scoring but now disqualified race gets max net points because of disqualification:
assertEquals(Util.size(bestScoringRaceColumn.getTrackedRace(defaultFleet).getRace().getCompetitors())+1,
leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getNetPoints());
leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getNetPoints(), 0.000000001);
// now assert that it gets discarded because due to disqualification it scores worse than all others:
assertEquals(0, leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getTotalPoints());
assertEquals(0, leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getTotalPoints(), 0.000000001);
}
@Test
@@ -162,10 +162,10 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
scoreCorrection.setMaxPointsReason(competitor, bestScoringRaceColumn, MaxPointsReason.DND);
// assert that best scoring but now disqualified race gets max net points because of disqualification:
assertEquals(Util.size(bestScoringRaceColumn.getTrackedRace(defaultFleet).getRace().getCompetitors())+1,
leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getNetPoints());
leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getNetPoints(), 0.000000001);
// now assert that it does not get discarded because it's a DND
assertEquals(Util.size(bestScoringRaceColumn.getTrackedRace(defaultFleet).getRace().getCompetitors())+1,
leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getTotalPoints());
leaderboard.getEntry(competitor, bestScoringRaceColumn, MillisecondsTimePoint.now()).getTotalPoints(), 0.000000001);
}
protected void testLeaderboard(int numberOfStartedRaces, int numberOfNotStartedRaces, int firstDiscardingThreshold,
@@ -208,30 +208,30 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
assertEquals(rank, leaderboard.getTrackedRank(competitor, raceColumn, now));
assertEquals(rank, leaderboard.getContent(now).get(key).getTrackedPoints());
assertEquals(rank, leaderboard.getEntry(competitor, raceColumn, now).getTrackedPoints());
assertEquals(rank, leaderboard.getNetPoints(competitor, raceColumn, now));
assertEquals(rank, leaderboard.getContent(now).get(key).getNetPoints());
assertEquals(rank, leaderboard.getEntry(competitor, raceColumn, now).getNetPoints());
assertEquals(rank, leaderboard.getNetPoints(competitor, raceColumn, now), 0.000000001);
assertEquals(rank, leaderboard.getContent(now).get(key).getNetPoints(), 0.000000001);
assertEquals(rank, leaderboard.getEntry(competitor, raceColumn, now).getNetPoints(), 0.000000001);
// One race is discarded because four races were started, and for [3-6) one race can be discarded.
// The discarded race is the worst of those started, so the one with rank 4.
int expectedNumberOfDiscardedRaces =
numberOfRacesFromWhichToDiscard < firstDiscardingThreshold ? 0 : numberOfRacesFromWhichToDiscard < secondDiscardingThreshold ? 1 : 2;
boolean discarded = ranksOfNonMedalStartedRaces.indexOf(rank) >= ranksOfNonMedalStartedRaces.size()-expectedNumberOfDiscardedRaces;
int expected = discarded ? 0 : rank==medalRacePoints?2*rank:rank;
assertEquals(expected, leaderboard.getTotalPoints(competitor, raceColumn, now));
assertEquals(expected, leaderboard.getContent(now).get(key).getTotalPoints());
assertEquals(expected, leaderboard.getEntry(competitor, raceColumn, now).getTotalPoints());
assertEquals(expected, leaderboard.getTotalPoints(competitor, raceColumn, now), 0.000000001);
assertEquals(expected, leaderboard.getContent(now).get(key).getTotalPoints(), 0.000000001);
assertEquals(expected, leaderboard.getEntry(competitor, raceColumn, now).getTotalPoints(), 0.000000001);
totalPoints += leaderboard.getContent(now).get(key).getTotalPoints();
} else {
assertEquals(0, leaderboard.getTrackedRank(competitor, raceColumn, now));
assertEquals(0, leaderboard.getNetPoints(competitor, raceColumn, now));
assertEquals(0, leaderboard.getNetPoints(competitor, raceColumn, now), 0.000000001);
assertEquals(0, leaderboard.getContent(now).get(key).getTrackedPoints());
assertEquals(0, leaderboard.getContent(now).get(key).getNetPoints());
assertEquals(0, leaderboard.getContent(now).get(key).getNetPoints(), 0.000000001);
assertEquals(0, leaderboard.getEntry(competitor, raceColumn, now).getTrackedPoints());
assertEquals(0, leaderboard.getEntry(competitor, raceColumn, now).getNetPoints());
assertEquals(0, leaderboard.getEntry(competitor, raceColumn, now).getNetPoints(), 0.000000001);
// no increment on totalPoints
}
}
assertEquals(totalPoints, leaderboard.getTotalPoints(competitor, now));
assertEquals(totalPoints, leaderboard.getTotalPoints(competitor, now), 0.000000001);
}
private int getMedalRacePoints(Competitor competitor, TimePoint at, Fleet fleet) throws NoWindException {
@@ -87,12 +87,12 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
assertEquals(competitors.get(5), rankedCompetitors.get(9));
// Now test the total points and make sure the other competitors advanced by one, too
assertEquals(11, leaderboard.getTotalPoints(competitors.get(5), f1Column, now));
assertEquals(11, leaderboard.getTotalPoints(competitors.get(5), f1Column, now), 0.000000001);
for (int i=0; i<5; i++) {
assertEquals(i+1, leaderboard.getTotalPoints(competitors.get(i), f1Column, now));
assertEquals(i+1, leaderboard.getTotalPoints(competitors.get(i), f1Column, now), 0.000000001);
}
for (int i=6; i<10; i++) {
assertEquals(i, leaderboard.getTotalPoints(competitors.get(i), f1Column, now));
assertEquals(i, leaderboard.getTotalPoints(competitors.get(i), f1Column, now), 0.000000001);
}
}
@@ -198,7 +198,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", f1, f2, f3);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later));
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later), 0.000000001);
assertEquals(Arrays.asList(new Competitor[] { c[0], c[1], c[2] }), rankedCompetitors);
}
@@ -217,7 +217,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", f1, f2, f3, f4, f5, f6);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later));
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later), 0.000000001);
assertTrue(rankedCompetitors.indexOf(c[0]) == rankedCompetitors.indexOf(c[1])-1);
}
@@ -235,7 +235,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
createAndAttachTrackedRaces(series.get(2), "Medal", m1);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
// assert that both have equal score
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later));
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later), 0.000000001);
// assert that c[0] ranks better than c[1] (reason: c[0] ranked better in medal race)
assertEquals(rankedCompetitors.indexOf(c[0]), rankedCompetitors.indexOf(c[1])-1);
}
@@ -255,7 +255,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", f1, f2, f3, f4, f5, f6);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later));
assertEquals(leaderboard.getTotalPoints(c[0], later), leaderboard.getTotalPoints(c[1], later), 0.000000001);
assertEquals(rankedCompetitors.indexOf(c[0]), rankedCompetitors.indexOf(c[1])-1);
}
@@ -19,9 +19,9 @@ import com.sap.sailing.domain.tracking.TrackedRace;
*
*/
public interface DelayedLeaderboardCorrections extends RaceColumnListener, Serializable {
void correctScore(String competitorName, RaceColumn raceColumn, int correctedScore);
void correctScore(String competitorName, RaceColumn raceColumn, double correctedScore);
void setCarriedPoints(String competitorName, int carriedPoints);
void setCarriedPoints(String competitorName, double carriedPoints);
void setMaxPointsReason(String competitorName, RaceColumn raceColumn, MaxPointsReason maxPointsReason);
@@ -40,8 +40,8 @@ public interface Leaderboard extends Named {
*/
public interface Entry {
int getTrackedPoints();
int getNetPoints() throws NoWindException;
int getTotalPoints() throws NoWindException;
double getNetPoints() throws NoWindException;
double getTotalPoints() throws NoWindException;
MaxPointsReason getMaxPointsReason();
boolean isDiscarded() throws NoWindException;
/**
@@ -77,7 +77,7 @@ public interface Leaderboard extends Named {
* the <code>competitor</code>. Returns <code>0</code> if there is no carried points definition for
* <code>competitor</code>.
*/
int getCarriedPoints(Competitor competitor);
double getCarriedPoints(Competitor competitor);
/**
* Shorthand for {@link TrackedRace#getRank(Competitor, com.sap.sailing.domain.common.TimePoint)} with the
@@ -106,7 +106,7 @@ public interface Leaderboard extends Named {
* @param race
* a race that is contained in the {@link #getRaceColumns()} result
*/
int getNetPoints(Competitor competitor, RaceColumn race, TimePoint timePoint) throws NoWindException;
double getNetPoints(Competitor competitor, RaceColumn race, TimePoint timePoint) throws NoWindException;
/**
* Tells if and why a competitor received "penalty" points for a race (however the scoring rules define the
@@ -125,7 +125,7 @@ public interface Leaderboard extends Named {
* @param race
* a race that is contained in the {@link #getRaceColumns()} result
*/
int getTotalPoints(Competitor competitor, RaceColumn race, TimePoint timePoint) throws NoWindException;
double getTotalPoints(Competitor competitor, RaceColumn race, TimePoint timePoint) throws NoWindException;
/**
* Tells whether the contribution of <code>raceColumn</code> is discarded in the current leaderboard's standings for
@@ -139,7 +139,7 @@ public interface Leaderboard extends Named {
* Sums up the {@link #getTotalPoints(Competitor, TrackedRace, TimePoint) total points} of <code>competitor</code>
* across all races tracked by this leaderboard.
*/
int getTotalPoints(Competitor competitor, TimePoint timePoint) throws NoWindException;
double getTotalPoints(Competitor competitor, TimePoint timePoint) throws NoWindException;
/**
* Sorts the competitors according to their ranking in the race column specified. Only competitors who have a score
@@ -191,7 +191,7 @@ public interface Leaderboard extends Named {
* simply added to the scores tracked by this leaderboard in the {@link #getTotalPoints(Competitor, TimePoint)}
* method.
*/
void setCarriedPoints(Competitor competitor, int carriedPoints);
void setCarriedPoints(Competitor competitor, double carriedPoints);
/**
* Reverses the effect of {@link #setCarriedPoints(Competitor, int)}, i.e., afterwards, asking {@link #getCarriedPoints(Competitor)}
@@ -21,7 +21,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
*/
public interface ScoreCorrection extends Serializable {
public interface Result {
int getCorrectedScore();
double getCorrectedScore();
MaxPointsReason getMaxPointsReason();
boolean isCorrected();
}
@@ -1,25 +0,0 @@
package com.sap.sailing.domain.leaderboard;
import java.math.BigDecimal;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.TrackedRace;
/**
* Tells how ranks and disqualifications of a {@link TrackedRace} are converted into points in the scope
* of a {@link Regatta}, also considering rules for discarding results. Different implementations may, e.g.,
* distinguish between low-point and high-point scoring schemes, schemes where a winner's score is further
* improved as well as different discarding thresholds.
*
* @author Axel Uhl (D043530)
*
*/
public interface ScoringRules {
/**
* Note that scores can be fractional numbers, e.g., if the scoring rule determines that the winner's rank
* is divided by two to obtain their score.
*/
BigDecimal getScore(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint);
}
@@ -17,7 +17,7 @@ public interface SettableScoreCorrection extends ScoreCorrection {
MaxPointsReason getMaxPointsReason(Competitor competitor, RaceColumn raceColumn);
void correctScore(Competitor competitor, RaceColumn raceColumn, int points);
void correctScore(Competitor competitor, RaceColumn raceColumn, double points);
/**
* Removes a score correction which makes the competitor's score for <code>raceColumn</code> to fall back to the score
@@ -29,7 +29,7 @@ public interface SettableScoreCorrection extends ScoreCorrection {
* @return <code>null</code> if not set for the competitor, e.g., because no correction was made or an explicit
* {@link MaxPointsReason} was provided for the competitor.
*/
Integer getExplicitScoreCorrection(Competitor competitor, RaceColumn raceColumn);
Double getExplicitScoreCorrection(Competitor competitor, RaceColumn raceColumn);
boolean hasCorrectionFor(RaceColumn raceInLeaderboard);
@@ -59,9 +59,9 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
* with aggregated results of races not tracked / displayed by this leaderboard in detail. The points
* provided by this map are considered by {@link #getTotalPoints(Competitor, TimePoint)}.
*/
private final Map<Competitor, Integer> carriedPoints;
private final Map<Competitor, Double> carriedPoints;
private final Comparator<Integer> scoreComparator;
private final Comparator<Double> scoreComparator;
private Set<RaceColumnListener> raceColumnListeners;
@@ -79,14 +79,14 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
*/
private class EntryImpl implements Entry {
private final Callable<Integer> trackedPoints;
private final int netPoints;
private final double netPoints;
private final boolean isNetPointsCorrected;
private final int totalPoints;
private final double totalPoints;
private final MaxPointsReason maxPointsReason;
private final boolean discarded;
private final Fleet fleet;
private EntryImpl(Callable<Integer> trackedPoints, int netPoints, boolean isNetPointsCorrected, int totalPoints,
private EntryImpl(Callable<Integer> trackedPoints, double netPoints, boolean isNetPointsCorrected, double totalPoints,
MaxPointsReason maxPointsReason, boolean discarded, Fleet fleet) {
super();
this.trackedPoints = trackedPoints;
@@ -106,7 +106,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
}
}
@Override
public int getNetPoints() {
public double getNetPoints() {
return netPoints;
}
@Override
@@ -114,7 +114,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
return isNetPointsCorrected;
}
@Override
public int getTotalPoints() {
public double getTotalPoints() {
return totalPoints;
}
@Override
@@ -136,8 +136,8 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
* @param name must not be <code>null</code>
*/
public AbstractLeaderboardImpl(SettableScoreCorrection scoreCorrection,
ThresholdBasedResultDiscardingRule resultDiscardingRule, Comparator<Integer> scoreComparator) {
this.carriedPoints = new HashMap<Competitor, Integer>();
ThresholdBasedResultDiscardingRule resultDiscardingRule, Comparator<Double> scoreComparator) {
this.carriedPoints = new HashMap<Competitor, Double>();
this.scoreCorrection = scoreCorrection;
this.displayNames = new HashMap<Competitor, String>();
this.resultDiscardingRule = resultDiscardingRule;
@@ -264,7 +264,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
}
@Override
public int getNetPoints(final Competitor competitor, final RaceColumn raceColumn, final TimePoint timePoint) throws NoWindException {
public double getNetPoints(final Competitor competitor, final RaceColumn raceColumn, final TimePoint timePoint) throws NoWindException {
return getScoreCorrection().getCorrectedScore(
new Callable<Integer>() {
public Integer call() throws NoWindException {
@@ -288,15 +288,15 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
}
@Override
public int getTotalPoints(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) throws NoWindException {
public double getTotalPoints(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint) throws NoWindException {
return isDiscarded(competitor, raceColumn, timePoint) ?
0 :
(raceColumn.isMedalRace() ? MEDAL_RACE_FACTOR : 1) * getNetPoints(competitor, raceColumn, timePoint);
}
@Override
public int getTotalPoints(Competitor competitor, TimePoint timePoint) throws NoWindException {
int result = getCarriedPoints(competitor);
public double getTotalPoints(Competitor competitor, TimePoint timePoint) throws NoWindException {
double result = getCarriedPoints(competitor);
for (RaceColumn r : getRaceColumns()) {
result += getTotalPoints(competitor, r, timePoint);
}
@@ -357,13 +357,13 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
}
@Override
public void setCarriedPoints(Competitor competitor, int carriedPoints) {
public void setCarriedPoints(Competitor competitor, double carriedPoints) {
this.carriedPoints.put(competitor, carriedPoints);
}
@Override
public int getCarriedPoints(Competitor competitor) {
Integer result = carriedPoints.get(competitor);
public double getCarriedPoints(Competitor competitor) {
Double result = carriedPoints.get(competitor);
return result == null ? 0 : result;
}
@@ -418,11 +418,11 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
*/
@Override
public List<Competitor> getCompetitorsFromBestToWorst(final RaceColumn raceColumn, TimePoint timePoint) throws NoWindException {
final Map<Competitor, Pair<Integer, Fleet>> netPointsAndFleet = new HashMap<Competitor, Pair<Integer, Fleet>>();
final Map<Competitor, Pair<Double, Fleet>> netPointsAndFleet = new HashMap<Competitor, Pair<Double, Fleet>>();
for (Competitor competitor : getCompetitors()) {
int netPoints = getNetPoints(competitor, raceColumn, timePoint);
double netPoints = getNetPoints(competitor, raceColumn, timePoint);
if (netPoints != 0) {
netPointsAndFleet.put(competitor, new Pair<Integer, Fleet>(netPoints, raceColumn.getFleetOfCompetitor(competitor)));
netPointsAndFleet.put(competitor, new Pair<Double, Fleet>(netPoints, raceColumn.getFleetOfCompetitor(competitor)));
}
}
List<Competitor> result = new ArrayList<Competitor>(netPointsAndFleet.keySet());
@@ -36,7 +36,7 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
private String name;
public FlexibleLeaderboardImpl(String name, SettableScoreCorrection scoreCorrection,
ThresholdBasedResultDiscardingRule resultDiscardingRule, Comparator<Integer> scoreComparator) {
ThresholdBasedResultDiscardingRule resultDiscardingRule, Comparator<Double> scoreComparator) {
super(scoreCorrection, resultDiscardingRule, scoreComparator);
if (name == null) {
throw new IllegalArgumentException("A leaderboard's name must not be null");
@@ -47,14 +47,14 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
*/
public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
private final Leaderboard leaderboard;
private final Comparator<Integer> scoreComparator;
private final Map<Pair<Competitor, RaceColumn>, Integer> totalPointsCache;
private final Comparator<Double> scoreComparator;
private final Map<Pair<Competitor, RaceColumn>, Double> totalPointsCache;
public LeaderboardTotalRankComparator(Leaderboard leaderboard, TimePoint timePoint, Comparator<Integer> scoreComparator) throws NoWindException {
public LeaderboardTotalRankComparator(Leaderboard leaderboard, TimePoint timePoint, Comparator<Double> scoreComparator) throws NoWindException {
super();
this.leaderboard = leaderboard;
this.scoreComparator = scoreComparator;
totalPointsCache = new HashMap<Pair<Competitor, RaceColumn>, Integer>();
totalPointsCache = new HashMap<Pair<Competitor, RaceColumn>, Double>();
for (Competitor competitor : leaderboard.getCompetitors()) {
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
totalPointsCache.put(new Pair<Competitor, RaceColumn>(competitor, raceColumn),
@@ -69,20 +69,20 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
@Override
public int compare(Competitor o1, Competitor o2) {
List<Integer> o1Scores = new ArrayList<Integer>();
List<Integer> o2Scores = new ArrayList<Integer>();
List<Double> o1Scores = new ArrayList<Double>();
List<Double> o2Scores = new ArrayList<Double>();
int o1ScoreSum = 0;
int o2ScoreSum = 0;
int o1MedalRaceScore = 0;
int o2MedalRaceScore = 0;
double o1MedalRaceScore = 0;
double o2MedalRaceScore = 0;
for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) {
int preemptiveColumnResult = 0;
final int o1Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o1, raceColumn));
final double o1Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o1, raceColumn));
if (o1Score != 0) {
o1Scores.add(o1Score);
o1ScoreSum += o1Score;
}
final int o2Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o2, raceColumn));
final double o2Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o2, raceColumn));
if (o2Score != 0) {
o2Scores.add(o2Score);
o2ScoreSum += o2Score;
@@ -123,7 +123,7 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
* Precondition: either both scored in medal race or both didn't. If both scored, the better score wins.
* This is to be applied only if the total score of both competitors are equal to each other.
*/
private int compareByMedalRaceScore(int o1MedalRaceScore, int o2MedalRaceScore) {
private int compareByMedalRaceScore(double o1MedalRaceScore, double o2MedalRaceScore) {
assert o1MedalRaceScore != 0 || o2MedalRaceScore == 0;
if (o1MedalRaceScore != 0) {
return getScoreComparator().compare(o1MedalRaceScore, o2MedalRaceScore);
@@ -185,7 +185,7 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
return result;
}
private int compareByMedalRaceParticipation(int o1Score, int o2Score) {
private int compareByMedalRaceParticipation(double o1Score, double o2Score) {
// if only one scored in medal race, this decides the order and returns immediately
if (o1Score == 0) {
if (o2Score != 0) {
@@ -207,14 +207,14 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
* @param o2Scores
* @return
*/
protected int compareByBetterScore(List<Integer> o1Scores, List<Integer> o2Scores) {
protected int compareByBetterScore(List<Double> o1Scores, List<Double> o2Scores) {
assert o1Scores.size() == o2Scores.size();
Comparator<Integer> scoreComparator = getScoreComparator();
Comparator<Double> scoreComparator = getScoreComparator();
Collections.sort(o1Scores, scoreComparator);
Collections.sort(o2Scores, scoreComparator);
// now both lists are sorted from best to worst score
Iterator<Integer> o1Iter = o1Scores.iterator();
Iterator<Integer> o2Iter = o2Scores.iterator();
Iterator<Double> o1Iter = o1Scores.iterator();
Iterator<Double> o2Iter = o2Scores.iterator();
int result = 0;
while (result == 0 && o1Iter.hasNext() && o2Iter.hasNext()) {
result = scoreComparator.compare(o1Iter.next(), o2Iter.next());
@@ -227,14 +227,14 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
* scheme where lesser scores compare "better" which again means "lesser." Therefore, the comparator retunred compares
* the integer numbers by their natural ordering.
*/
protected Comparator<Integer> getScoreComparator() {
protected Comparator<Double> getScoreComparator() {
return scoreComparator;
}
/**
* This implementation ranks a competitor better (lesser) if it has the lower score sum
*/
protected int compareByScoreSum(int o1ScoreSum, int o2ScoreSum) {
protected int compareByScoreSum(double o1ScoreSum, double o2ScoreSum) {
return getScoreComparator().compare(o1ScoreSum, o2ScoreSum);
}
@@ -9,12 +9,12 @@ import java.util.Comparator;
* @author Axel Uhl (D043530)
*
*/
public class LowerScoreIsBetter implements Comparator<Integer>, Serializable {
public class LowerScoreIsBetter implements Comparator<Double>, Serializable {
private static final long serialVersionUID = -2767385186133743330L;
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
public int compare(Double o1, Double o2) {
return Double.valueOf(o1).compareTo(Double.valueOf(o2));
}
}
@@ -29,7 +29,7 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
private final Regatta regatta;
public RegattaLeaderboardImpl(Regatta regatta, SettableScoreCorrection scoreCorrection,
ThresholdBasedResultDiscardingRule resultDiscardingRule, Comparator<Integer> scoreComparator) {
ThresholdBasedResultDiscardingRule resultDiscardingRule, Comparator<Double> scoreComparator) {
super(scoreCorrection, resultDiscardingRule, scoreComparator);
this.regatta = regatta;
regatta.addRaceColumnListener(this);
@@ -57,7 +57,8 @@ public class ResultDiscardingRuleImpl implements ThresholdBasedResultDiscardingR
@Override
public int compare(RaceColumn o1, RaceColumn o2) {
try {
return leaderboard.getNetPoints(competitor, o1, timePoint) - leaderboard.getNetPoints(competitor, o2, timePoint);
return Double.valueOf(leaderboard.getNetPoints(competitor, o1, timePoint)).compareTo(
Double.valueOf(leaderboard.getNetPoints(competitor, o2, timePoint)));
} catch (NoWindException e) {
throw new NoWindError(e);
}
@@ -33,11 +33,11 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
/**
* If no score correction is provided here, the uncorrected points are the default.
*/
private final Map<Pair<Competitor, RaceColumn>, Integer> correctedScores;
private final Map<Pair<Competitor, RaceColumn>, Double> correctedScores;
public ScoreCorrectionImpl() {
this.maxPointsReasons = new HashMap<Util.Pair<Competitor,RaceColumn>, MaxPointsReason>();
this.correctedScores = new HashMap<Util.Pair<Competitor,RaceColumn>, Integer>();
this.correctedScores = new HashMap<Util.Pair<Competitor,RaceColumn>, Double>();
}
@Override
@@ -51,7 +51,7 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
}
@Override
public void correctScore(Competitor competitor, RaceColumn raceColumn, int points) {
public void correctScore(Competitor competitor, RaceColumn raceColumn, double points) {
correctedScores.put(raceColumn.getKey(competitor), points);
}
@@ -85,21 +85,21 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
@Override
public Result getCorrectedScore(Callable<Integer> uncorrectedScore, final Competitor competitor, final RaceColumn raceColumn,
TimePoint timePoint, int numberOfCompetitorsInLeaderboard) {
int result;
double result;
final MaxPointsReason maxPointsReason = getMaxPointsReason(competitor, raceColumn);
if (maxPointsReason == MaxPointsReason.NONE) {
result = getCorrectedNonMaxedScore(competitor, raceColumn, uncorrectedScore);
} else {
// allow explicit override even when max points reason is specified; calculation may be wrong,
// e.g., in case we have an untracked race and the number of competitors is estimated incorrectly
Integer correctedNonMaxedScore = correctedScores.get(raceColumn.getKey(competitor));
Double correctedNonMaxedScore = correctedScores.get(raceColumn.getKey(competitor));
if (correctedNonMaxedScore == null) {
result = getMaxPoints(raceColumn.getTrackedRace(competitor), numberOfCompetitorsInLeaderboard);
} else {
result = correctedNonMaxedScore;
}
}
final int correctedScore = result;
final double correctedScore = result;
return new Result() {
@Override
public MaxPointsReason getMaxPointsReason() {
@@ -107,7 +107,7 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
}
@Override
public int getCorrectedScore() {
public double getCorrectedScore() {
return correctedScore;
}
@@ -123,8 +123,8 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
* reasons, computes the corrected score. If {@link #correctedScores} contains an entry for the <code>competitor</code>'s key,
* it is used. Otherwise, the <code>uncorrectedScore</code> is returned.
*/
protected int getCorrectedNonMaxedScore(Competitor competitor, RaceColumn raceColumn, Callable<Integer> uncorrectedScore) {
Integer correctedNonMaxedScore = correctedScores.get(raceColumn.getKey(competitor));
protected double getCorrectedNonMaxedScore(Competitor competitor, RaceColumn raceColumn, Callable<Integer> uncorrectedScore) {
Double correctedNonMaxedScore = correctedScores.get(raceColumn.getKey(competitor));
if (correctedNonMaxedScore == null) {
try {
return uncorrectedScore.call();
@@ -141,7 +141,7 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
}
@Override
public Integer getExplicitScoreCorrection(Competitor competitor, RaceColumn raceColumn) {
public Double getExplicitScoreCorrection(Competitor competitor, RaceColumn raceColumn) {
return correctedScores.get(raceColumn.getKey(competitor));
}
@@ -168,11 +168,11 @@ public interface SailingService extends RemoteService {
* @return the new net points in {@link Pair#getA()} and the new total points in {@link Pair#getB()} for time point
* <code>date</code> after the max points reason has been updated to <code>maxPointsReasonAsString</code>.
*/
Triple<Integer, Integer, Boolean> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString,
Triple<Double, Double, Boolean> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString,
String raceColumnName, MaxPointsReason maxPointsReason, Date date) throws NoWindException;
Triple<Integer, Integer, Boolean> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString,
String columnName, Integer correctedScore, Date date) throws NoWindException;
Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString,
String columnName, Double correctedScore, Date date) throws NoWindException;
void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, String displayName);
@@ -229,10 +229,10 @@ public interface SailingServiceAsync {
void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Integer carriedPoints, AsyncCallback<Void> callback);
void updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName,
MaxPointsReason maxPointsReason, Date date, AsyncCallback<Triple<Integer, Integer, Boolean>> asyncCallback);
MaxPointsReason maxPointsReason, Date date, AsyncCallback<Triple<Double, Double, Boolean>> asyncCallback);
void updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString, String columnName,
Integer correctedScore, Date date, AsyncCallback<Triple<Integer, Integer, Boolean>> asyncCallback);
Double correctedScore, Date date, AsyncCallback<Triple<Double, Double, Boolean>> asyncCallback);
void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates,
AsyncCallback<Void> callback);
@@ -564,7 +564,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
@Override
public String getValue(LeaderboardRowDTO object) {
final int totalPoints = object.fieldsByRaceColumnName.get(getRaceColumnName()).totalPoints;
final double totalPoints = object.fieldsByRaceColumnName.get(getRaceColumnName()).totalPoints;
return "" + (totalPoints == 0 ? "" : totalPoints);
}
@@ -835,7 +835,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
@Override
public String getValue(LeaderboardRowDTO object) {
int totalPoints = getLeaderboard().getTotalPoints(object);
double totalPoints = getLeaderboard().getTotalPoints(object);
return "" + (totalPoints==0 ? "" : totalPoints);
}
@@ -888,8 +888,15 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
return new Comparator<LeaderboardRowDTO>() {
@Override
public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) {
return (o1.carriedPoints == null ? 0 : o1.carriedPoints)
- (o2.carriedPoints == null ? 0 : o2.carriedPoints);
Double o1CarriedPoints = o1.carriedPoints;
if (o1CarriedPoints == null) {
o1CarriedPoints = 0.0;
}
Double o2CarriedPoints = o2.carriedPoints;
if (o2CarriedPoints == null) {
o2CarriedPoints = 0.0;
}
return o1CarriedPoints.compareTo(o2CarriedPoints);
}
};
}
@@ -74,7 +74,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
@Override
public void onSuccess(Void v) {
row.carriedPoints = value==null||value.length()==0 ? null : Integer.valueOf(value.trim());
row.carriedPoints = value==null||value.length()==0 ? null : Double.valueOf(value.trim());
EditableLeaderboardPanel.this.getData().getList().set(rowIndex, row);
}
});
@@ -227,7 +227,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
getBusyIndicator().setBusy(true);
getSailingService().updateLeaderboardMaxPointsReason(getLeaderboardName(), row.competitor.id,
raceColumnName, value == null || value.trim().length() == 0 ? null : MaxPointsReason.valueOf(value.trim()),
getLeaderboardDisplayDate(), new AsyncCallback<Triple<Integer, Integer, Boolean>>() {
getLeaderboardDisplayDate(), new AsyncCallback<Triple<Double, Double, Boolean>>() {
@Override
public void onFailure(Throwable t) {
getBusyIndicator().setBusy(false);
@@ -238,7 +238,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
}
@Override
public void onSuccess(Triple<Integer, Integer, Boolean> newNetAndTotalPointsAndIsCorrected) {
public void onSuccess(Triple<Double, Double, Boolean> newNetAndTotalPointsAndIsCorrected) {
getBusyIndicator().setBusy(false);
row.fieldsByRaceColumnName.get(raceColumnName).reasonForMaxPoints = value == null
|| value.length() == 0 ? null : MaxPointsReason.valueOf(value.trim());
@@ -322,8 +322,8 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
getWhiteboardOwner().whiteboardProduced(whiteboard);
getBusyIndicator().setBusy(true);
getSailingService().updateLeaderboardScoreCorrection(getLeaderboardName(), row.competitor.id, raceName,
value == null || value.trim().length() == 0 ? null : Integer.valueOf(value.trim()), getLeaderboardDisplayDate(),
new AsyncCallback<Triple<Integer, Integer, Boolean>>() {
value == null || value.trim().length() == 0 ? null : Double.valueOf(value.trim()), getLeaderboardDisplayDate(),
new AsyncCallback<Triple<Double, Double, Boolean>>() {
@Override
public void onFailure(Throwable t) {
getBusyIndicator().setBusy(false);
@@ -334,7 +334,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
}
@Override
public void onSuccess(Triple<Integer, Integer, Boolean> newNetAndTotalPointsAndIsCorrected) {
public void onSuccess(Triple<Double, Double, Boolean> newNetAndTotalPointsAndIsCorrected) {
getBusyIndicator().setBusy(false);
final LeaderboardEntryDTO leaderboardEntryDTO = row.fieldsByRaceColumnName.get(raceName);
leaderboardEntryDTO.netPoints = value == null || value.length() == 0 ? newNetAndTotalPointsAndIsCorrected
@@ -1949,7 +1949,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
}
@Override
public Triple<Integer, Integer, Boolean> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName,
public Triple<Double, Double, Boolean> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName,
MaxPointsReason maxPointsReason, Date date) throws NoWindException {
return getService().apply(
new UpdateLeaderboardMaxPointsReason(leaderboardName, raceColumnName, competitorIdAsString,
@@ -1957,8 +1957,8 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
}
@Override
public Triple<Integer, Integer, Boolean> updateLeaderboardScoreCorrection(String leaderboardName,
String competitorIdAsString, String columnName, Integer correctedScore, Date date) throws NoWindException {
public Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(String leaderboardName,
String competitorIdAsString, String columnName, Double correctedScore, Date date) throws NoWindException {
return getService().apply(
new UpdateLeaderboardScoreCorrection(leaderboardName, columnName, competitorIdAsString, correctedScore,
new MillisecondsTimePoint(date)));
@@ -1967,8 +1967,8 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
@Override
public void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates) throws NoWindException {
Date dateForResults = new Date(); // we don't care about the result date/time here; use current date as default
for (Map.Entry<String, Map<String, Integer>> e : updates.getScoreUpdatesForRaceColumnByCompetitorIdAsString().entrySet()) {
for (Map.Entry<String, Integer> raceColumnNameAndCorrectedScore : e.getValue().entrySet()) {
for (Map.Entry<String, Map<String, Double>> e : updates.getScoreUpdatesForRaceColumnByCompetitorIdAsString().entrySet()) {
for (Map.Entry<String, Double> raceColumnNameAndCorrectedScore : e.getValue().entrySet()) {
updateLeaderboardScoreCorrection(updates.getLeaderboardName(), e.getKey(),
raceColumnNameAndCorrectedScore.getKey(), raceColumnNameAndCorrectedScore.getValue(), dateForResults);
}
@@ -69,16 +69,16 @@ public abstract class AbstractLeaderboardDTO implements IsSerializable {
return false;
}
public int getTotalPoints(LeaderboardRowDTO object) {
int totalPoints = object.carriedPoints == null ? 0 : object.carriedPoints;
public double getTotalPoints(LeaderboardRowDTO object) {
double totalPoints = object.carriedPoints == null ? 0 : object.carriedPoints;
for (LeaderboardEntryDTO e : object.fieldsByRaceColumnName.values()) {
totalPoints += e.totalPoints;
}
return totalPoints;
}
public int getNetPoints(CompetitorDTO competitor, String nameOfLastRaceSoFar) {
int result = 0;
public double getNetPoints(CompetitorDTO competitor, String nameOfLastRaceSoFar) {
double result = 0;
LeaderboardRowDTO row = rows.get(competitor);
if (row != null) {
LeaderboardEntryDTO field = row.fieldsByRaceColumnName.get(nameOfLastRaceSoFar);
@@ -16,20 +16,20 @@ import com.sap.sailing.domain.common.MaxPointsReason;
public class BulkScoreCorrectionDTO implements IsSerializable {
private String leaderboardName;
private Map<String, Map<String, MaxPointsReason>> maxPointsUpdatesForRaceColumnByCompetitorIdAsString;
private Map<String, Map<String, Integer>> scoreUpdatesForRaceColumnByCompetitorIdAsString;
private Map<String, Map<String, Double>> scoreUpdatesForRaceColumnByCompetitorIdAsString;
public BulkScoreCorrectionDTO() {}
public BulkScoreCorrectionDTO(String leaderboardName) {
this.leaderboardName = leaderboardName;
maxPointsUpdatesForRaceColumnByCompetitorIdAsString = new HashMap<String, Map<String,MaxPointsReason>>();
scoreUpdatesForRaceColumnByCompetitorIdAsString = new HashMap<String, Map<String,Integer>>();
scoreUpdatesForRaceColumnByCompetitorIdAsString = new HashMap<String, Map<String, Double>>();
}
public void addScoreUpdate(CompetitorDTO competitor, RaceColumnDTO raceColumn, int newScore) {
Map<String, Integer> map = scoreUpdatesForRaceColumnByCompetitorIdAsString.get(competitor.id);
public void addScoreUpdate(CompetitorDTO competitor, RaceColumnDTO raceColumn, double newScore) {
Map<String, Double> map = scoreUpdatesForRaceColumnByCompetitorIdAsString.get(competitor.id);
if (map == null) {
map = new HashMap<String, Integer>();
map = new HashMap<String, Double>();
scoreUpdatesForRaceColumnByCompetitorIdAsString.put(competitor.id, map);
}
map.put(raceColumn.name, newScore);
@@ -48,7 +48,7 @@ public class BulkScoreCorrectionDTO implements IsSerializable {
return maxPointsUpdatesForRaceColumnByCompetitorIdAsString;
}
public Map<String, Map<String, Integer>> getScoreUpdatesForRaceColumnByCompetitorIdAsString() {
public Map<String, Map<String, Double>> getScoreUpdatesForRaceColumnByCompetitorIdAsString() {
return scoreUpdatesForRaceColumnByCompetitorIdAsString;
}
@@ -26,14 +26,14 @@ public class LeaderboardEntryDTO implements IsSerializable {
*/
public MaxPointsReason reasonForMaxPoints;
public int netPoints;
public double netPoints;
/**
* Tells if the net points have been overridden by a score correction. Can be used to render differently in editing environment.
*/
public boolean netPointsCorrected;
public int totalPoints;
public double totalPoints;
public boolean discarded;
@@ -63,11 +63,11 @@ public class LeaderboardEntryDTO implements IsSerializable {
int result = 1;
result = prime * result + (discarded ? 1231 : 1237);
result = prime * result + ((legDetails == null) ? 0 : legDetails.hashCode());
result = prime * result + netPoints;
result = prime * result + (int) netPoints;
result = prime * result + ((averageCrossTrackErrorInMeters == null) ? 0 : averageCrossTrackErrorInMeters.hashCode());
result = prime * result + ((reasonForMaxPoints == null) ? 0 : reasonForMaxPoints.hashCode());
result = prime * result + ((windwardDistanceToOverallLeaderInMeters == null) ? 0 : windwardDistanceToOverallLeaderInMeters.hashCode());
result = prime * result + totalPoints;
result = prime * result + (int) totalPoints;
return result;
}
@@ -13,7 +13,7 @@ import com.google.gwt.user.client.rpc.IsSerializable;
public class LeaderboardRowDTO implements IsSerializable {
public CompetitorDTO competitor;
public Map<String, LeaderboardEntryDTO> fieldsByRaceColumnName;
public Integer carriedPoints;
public Double carriedPoints;
@Override
public int hashCode() {
@@ -48,7 +48,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
public void testStoreAndRetrieveLeaderboardWithCarryColumn() {
final String leaderboardName = "TestLeaderboard";
final String raceColumnName = "My First Race";
final int carriedPointsForWolfgangHunger = 3;
final double carriedPointsForWolfgangHunger = 3.7;
final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 };
FlexibleLeaderboardImpl leaderboard = new FlexibleLeaderboardImpl(leaderboardName, new ScoreCorrectionImpl(),
new ResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces), new LowerScoreIsBetter());
@@ -65,7 +65,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
.getDiscardIndexResultsStartingWithHowManyRaces()));
assertEquals(1, Util.size(loadedLeaderboard.getCompetitors()));
assertEquals(competitor, loadedLeaderboard.getCompetitors().iterator().next());
assertEquals(carriedPointsForWolfgangHunger, loadedLeaderboard.getCarriedPoints(competitor));
assertEquals(carriedPointsForWolfgangHunger, loadedLeaderboard.getCarriedPoints(competitor), 0.000000001);
}
@Test
@@ -73,7 +73,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
final String leaderboardName = "TestLeaderboard";
final String raceColumnName1 = "My First Race 1";
final String raceColumnName2 = "My First Race 2";
final int correctedPoints = 2;
final double correctedPoints = 2.75;
final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 };
FlexibleLeaderboardImpl leaderboard = new FlexibleLeaderboardImpl(leaderboardName, new ScoreCorrectionImpl(),
new ResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces), new LowerScoreIsBetter());
@@ -90,7 +90,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
RaceColumn loadedColumn2 = loadedLeaderboard.addRace(raceWithOneCompetitor2, raceColumnName2, /* medalRace, ignored */ false, leaderboard.getFleet(null));
assertEquals(leaderboardName, loadedLeaderboard.getName());
assertTrue(loadedLeaderboard.getScoreCorrection().isScoreCorrected(competitor, loadedColumn1));
assertEquals(correctedPoints, (int) loadedLeaderboard.getScoreCorrection().getExplicitScoreCorrection(competitor, loadedColumn1));
assertEquals(correctedPoints, (double) loadedLeaderboard.getScoreCorrection().getExplicitScoreCorrection(competitor, loadedColumn1), 0.00000001);
assertFalse(loadedLeaderboard.getScoreCorrection().isScoreCorrected(competitor, loadedColumn2));
}
@@ -125,7 +125,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
final String leaderboardName = "TestLeaderboard";
final String raceColumnName1 = "My First Race 1";
final String raceColumnName2 = "My First Race 2";
final int correctedPoints = 2;
final double correctedPoints = 2.55;
final MaxPointsReason maxPointsReason = MaxPointsReason.DNF;
final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 };
FlexibleLeaderboardImpl leaderboard = new FlexibleLeaderboardImpl(leaderboardName, new ScoreCorrectionImpl(),
@@ -144,7 +144,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
RaceColumn loadedColumn2 = loadedLeaderboard.addRace(raceWithOneCompetitor2, raceColumnName2, /* medalRace, ignored */ false, leaderboard.getFleet(null));
assertEquals(leaderboardName, loadedLeaderboard.getName());
assertTrue(loadedLeaderboard.getScoreCorrection().isScoreCorrected(competitor, loadedColumn1));
assertEquals(correctedPoints, (int) loadedLeaderboard.getScoreCorrection().getExplicitScoreCorrection(competitor, loadedColumn1));
assertEquals(correctedPoints, (double) loadedLeaderboard.getScoreCorrection().getExplicitScoreCorrection(competitor, loadedColumn1), 0.000000001);
assertTrue(loadedLeaderboard.getScoreCorrection().isScoreCorrected(competitor, loadedColumn2));
assertEquals(maxPointsReason, loadedLeaderboard.getScoreCorrection().getMaxPointsReason(competitor, loadedColumn2));
}
@@ -11,7 +11,7 @@ import com.sap.sailing.domain.leaderboard.Leaderboard.Entry;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboardMaxPointsReason extends AbstractLeaderboardColumnOperation<Triple<Integer, Integer, Boolean>> {
public class UpdateLeaderboardMaxPointsReason extends AbstractLeaderboardColumnOperation<Triple<Double, Double, Boolean>> {
private static final long serialVersionUID = -492130952256848047L;
private final String competitorIdAsString;
private final MaxPointsReason newMaxPointsReason;
@@ -38,7 +38,7 @@ public class UpdateLeaderboardMaxPointsReason extends AbstractLeaderboardColumnO
}
@Override
public Triple<Integer, Integer, Boolean> internalApplyTo(RacingEventService toState) throws NoWindException {
public Triple<Double, Double, Boolean> internalApplyTo(RacingEventService toState) throws NoWindException {
Leaderboard leaderboard = toState.getLeaderboardByName(getLeaderboardName());
if (leaderboard != null) {
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
@@ -51,7 +51,7 @@ public class UpdateLeaderboardMaxPointsReason extends AbstractLeaderboardColumnO
updateStoredLeaderboard(toState, leaderboard);
Entry updatedEntry = leaderboard.getEntry(competitor, raceColumn, timePoint);
boolean isScoreCorrected = leaderboard.getScoreCorrection().isScoreCorrected(competitor, raceColumn);
return new Triple<Integer, Integer, Boolean>(updatedEntry.getNetPoints(), updatedEntry.getTotalPoints(), isScoreCorrected);
return new Triple<Double, Double, Boolean>(updatedEntry.getNetPoints(), updatedEntry.getTotalPoints(), isScoreCorrected);
} else {
throw new IllegalArgumentException("Didn't find competitor with ID "+competitorIdAsString+" in leaderboard "+getLeaderboardName());
}
@@ -9,17 +9,17 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardColumnOperation<Triple<Integer, Integer, Boolean>> {
public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardColumnOperation<Triple<Double, Double, Boolean>> {
private static final long serialVersionUID = -977025759476022993L;
private final String competitorIdAsString;
private final Integer correctedScore;
private final Double correctedScore;
private final TimePoint timePoint;
/**
* @param timePoint the time point for which to deliver leaderboard results as the result of this operation
*/
public UpdateLeaderboardScoreCorrection(String leaderboardName, String columnName, String competitorIdAsString,
Integer correctedScore, TimePoint timePoint) {
Double correctedScore, TimePoint timePoint) {
super(leaderboardName, columnName);
this.competitorIdAsString = competitorIdAsString;
this.correctedScore = correctedScore;
@@ -39,10 +39,10 @@ public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardColumnO
}
@Override
public Triple<Integer, Integer, Boolean> internalApplyTo(RacingEventService toState) throws NoWindException {
public Triple<Double, Double, Boolean> internalApplyTo(RacingEventService toState) throws NoWindException {
Leaderboard leaderboard = toState.getLeaderboardByName(getLeaderboardName());
int newNetPoints;
int newTotalPoints;
double newNetPoints;
double newTotalPoints;
boolean isScoreCorrected;
if (leaderboard != null) {
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
@@ -64,7 +64,7 @@ public class UpdateLeaderboardScoreCorrection extends AbstractLeaderboardColumnO
throw new IllegalArgumentException("Didn't find leaderboard "+getLeaderboardName());
}
updateStoredLeaderboard(toState, leaderboard);
return new Triple<Integer, Integer, Boolean>(newNetPoints, newTotalPoints, isScoreCorrected);
return new Triple<Double, Double, Boolean>(newNetPoints, newTotalPoints, isScoreCorrected);
}
}