diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DelayedLeaderboardCorrectionsImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DelayedLeaderboardCorrectionsImpl.java
index 15981e2a3f9..d445b359113 100755
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DelayedLeaderboardCorrectionsImpl.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DelayedLeaderboardCorrectionsImpl.java
@@ -16,7 +16,7 @@ import com.sap.sailing.domain.base.RaceColumnListener;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.DelayedLeaderboardCorrections;
import com.sap.sailing.domain.leaderboard.Leaderboard;
-import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.tracking.TrackedRace;
@@ -401,7 +401,7 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
}
@Override
- public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule, ThresholdBasedResultDiscardingRule newDiscardingRule) {
+ public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
}
@Override
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
index fe20a1b22bb..da3d9973d81 100755
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
@@ -83,7 +83,7 @@ import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
-import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
+import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
@@ -238,7 +238,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
}
if (result == null) {
SettableScoreCorrection scoreCorrection = new ScoreCorrectionImpl();
- ThresholdBasedResultDiscardingRule resultDiscardingRule = loadResultDiscardingRule(dbLeaderboard);
+ ThresholdBasedResultDiscardingRule resultDiscardingRule = loadResultDiscardingRule(dbLeaderboard, FieldNames.LEADERBOARD_DISCARDING_THRESHOLDS);
String regattaName = (String) dbLeaderboard.get(FieldNames.REGATTA_NAME.name());
if (groupForMetaLeaderboard != null) {
result = new LeaderboardGroupMetaLeaderboard(groupForMetaLeaderboard, loadScoringScheme(dbLeaderboard), resultDiscardingRule);
@@ -314,17 +314,16 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
}
/**
- * @param dbLeaderboard expects to find a field named {@link FieldNames#LEADERBOARD_DISCARDING_THRESHOLDS}
+ * @param dbObject expects to find a field identified by field which holds a {@link BasicDBList}
*/
- private ThresholdBasedResultDiscardingRule loadResultDiscardingRule(DBObject dbLeaderboard) {
- BasicDBList dbDiscardIndexResultsStartingWithHowManyRaces = (BasicDBList) dbLeaderboard
- .get(FieldNames.LEADERBOARD_DISCARDING_THRESHOLDS.name());
+ private ThresholdBasedResultDiscardingRule loadResultDiscardingRule(DBObject dbObject, FieldNames field) {
+ BasicDBList dbDiscardIndexResultsStartingWithHowManyRaces = (BasicDBList) dbObject.get(field.name());
int[] discardIndexResultsStartingWithHowManyRaces = new int[dbDiscardIndexResultsStartingWithHowManyRaces.size()];
int i = 0;
for (Object discardingThresholdAsObject : dbDiscardIndexResultsStartingWithHowManyRaces) {
discardIndexResultsStartingWithHowManyRaces[i++] = (Integer) discardingThresholdAsObject;
}
- ThresholdBasedResultDiscardingRule resultDiscardingRule = new ResultDiscardingRuleImpl(
+ ThresholdBasedResultDiscardingRule resultDiscardingRule = new ThresholdBasedResultDiscardingRuleImpl(
discardIndexResultsStartingWithHowManyRaces);
return resultDiscardingRule;
}
@@ -917,6 +916,10 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
fleetsByName.values(),
raceColumnNames,
trackedRegattaRegistry);
+ if (dbSeries.get(FieldNames.SERIES_DISCARDING_THRESHOLDS.name()) != null) {
+ ThresholdBasedResultDiscardingRule resultDiscardingRule = loadResultDiscardingRule(dbSeries, FieldNames.SERIES_DISCARDING_THRESHOLDS);
+ series.setResultDiscardingRule(resultDiscardingRule);
+ }
loadRaceColumnRaceLinks(dbRaceColumns, series);
return series;
}
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java
index 02807f1736f..915625b5116 100755
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java
@@ -22,6 +22,7 @@ public enum FieldNames {
SERIES_IS_MEDAL,
SERIES_FLEETS,
SERIES_RACE_COLUMNS,
+ SERIES_DISCARDING_THRESHOLDS,
FLEET_NAME,
FLEET_ORDERING,
FLEET_COLOR,
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
index af0b4dc3707..95af524041c 100755
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
@@ -41,6 +41,7 @@ import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
@@ -237,8 +238,8 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
BasicDBObject dbScoreCorrections = new BasicDBObject();
storeScoreCorrections(leaderboard, dbScoreCorrections);
dbLeaderboard.put(FieldNames.LEADERBOARD_SCORE_CORRECTIONS.name(), dbScoreCorrections);
- final ThresholdBasedResultDiscardingRule resultDiscardingRule = leaderboard.getResultDiscardingRule();
- storeResultDiscardingRule(dbLeaderboard, resultDiscardingRule);
+ final ResultDiscardingRule resultDiscardingRule = leaderboard.getResultDiscardingRule();
+ storeResultDiscardingRule(dbLeaderboard, resultDiscardingRule, FieldNames.LEADERBOARD_DISCARDING_THRESHOLDS);
BasicDBList competitorDisplayNames = new BasicDBList();
for (Competitor competitor : leaderboard.getCompetitors()) {
String displayNameForCompetitor = leaderboard.getDisplayName(competitor);
@@ -252,13 +253,20 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
dbLeaderboard.put(FieldNames.LEADERBOARD_COMPETITOR_DISPLAY_NAMES.name(), competitorDisplayNames);
}
- private void storeResultDiscardingRule(BasicDBObject dbLeaderboard,
- final ThresholdBasedResultDiscardingRule resultDiscardingRule) {
- BasicDBList dbResultDiscardingThresholds = new BasicDBList();
- for (int threshold : resultDiscardingRule.getDiscardIndexResultsStartingWithHowManyRaces()) {
- dbResultDiscardingThresholds.add(threshold);
+ /**
+ * Stores the result discarding rule to dbObject's field identified by field if the result discarding
+ * rule is not null and is of type {@link ThresholdBasedResultDiscardingRule}. Otherwise, it is assumed that the
+ * result discarding rule is otherwise implicitly obtained, e.g., from a definition of a regatta with its series, stored elsewhere.
+ */
+ private void storeResultDiscardingRule(DBObject dbObject,
+ final ResultDiscardingRule resultDiscardingRule, FieldNames field) {
+ if (resultDiscardingRule != null && resultDiscardingRule instanceof ThresholdBasedResultDiscardingRule) {
+ BasicDBList dbResultDiscardingThresholds = new BasicDBList();
+ for (int threshold : ((ThresholdBasedResultDiscardingRule) resultDiscardingRule).getDiscardIndexResultsStartingWithHowManyRaces()) {
+ dbResultDiscardingThresholds.add(threshold);
+ }
+ dbObject.put(field.name(), dbResultDiscardingThresholds);
}
- dbLeaderboard.put(FieldNames.LEADERBOARD_DISCARDING_THRESHOLDS.name(), dbResultDiscardingThresholds);
}
private BasicDBObject storeRaceColumn(RaceColumn raceColumn) {
@@ -478,6 +486,9 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
dbRaceColumns.add(storeRaceColumn(raceColumn));
}
dbSeries.put(FieldNames.SERIES_RACE_COLUMNS.name(), dbRaceColumns);
+ if (s.getResultDiscardingRule() != null) {
+ storeResultDiscardingRule(dbSeries, s.getResultDiscardingRule(), FieldNames.SERIES_DISCARDING_THRESHOLDS);
+ }
return dbSeries;
}
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardForKielWeekTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardForKielWeekTest.java
index a5917d0586a..5613aa65226 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardForKielWeekTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardForKielWeekTest.java
@@ -21,7 +21,7 @@ import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
-import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
+import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
import com.sap.sailing.domain.tracking.impl.WindImpl;
import com.sap.sailing.domain.tractracadapter.ReceiverType;
@@ -37,7 +37,7 @@ public class LeaderboardForKielWeekTest extends OnlineTracTracBasedTest {
@Test
public void leaderboardWithOneRaceTest() throws URISyntaxException, NoWindException, IOException, InterruptedException {
leaderboard = new FlexibleLeaderboardImpl("Kiel Week 2011 505s", new ScoreCorrectionImpl(),
- new ResultDiscardingRuleImpl(new int[] { 3, 6 }), new LowPoint(), null);
+ new ThresholdBasedResultDiscardingRuleImpl(new int[] { 3, 6 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
MillisecondsTimePoint now = MillisecondsTimePoint.now();
loadRace("357c700a-9d9a-11e0-85be-406186cbf87c"); // 505 Race 2
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardOfflineTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardOfflineTest.java
index b2a12be2795..e8cc3d74568 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardOfflineTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardOfflineTest.java
@@ -37,7 +37,7 @@ import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
-import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
+import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithFixedRank;
import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithFixedRankAndManyCompetitors;
@@ -100,7 +100,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
@Test
public void ensureMedalRaceParamIsIgnoredIfRaceColumnAlreadyExists() {
- FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", new ScoreCorrectionImpl(), new ResultDiscardingRuleImpl(
+ FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", new ScoreCorrectionImpl(), new ThresholdBasedResultDiscardingRuleImpl(
new int[] { 5, 8 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
final String columnName = "abc";
@@ -113,7 +113,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
@Test
public void testRepeatedLeaderboardDTOCacheInvalidation() throws NoWindException, InterruptedException, ExecutionException {
- FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", new ScoreCorrectionImpl(), new ResultDiscardingRuleImpl(
+ FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", new ScoreCorrectionImpl(), new ThresholdBasedResultDiscardingRuleImpl(
new int[] { 5, 8 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
final String columnName = "abc";
@@ -169,7 +169,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
testRaces.add(r); // hash set should take care of more or less randomly permuting the races
}
ScoreCorrectionImpl scoreCorrection = new ScoreCorrectionImpl();
- FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ResultDiscardingRuleImpl(
+ FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ThresholdBasedResultDiscardingRuleImpl(
new int[] { 1 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
int i=0;
@@ -203,7 +203,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
testRace.addCompetitor(c2);
testRace.addCompetitor(c3); // this makes maxPoints==4
ScoreCorrectionImpl scoreCorrection = new ScoreCorrectionImpl();
- FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ResultDiscardingRuleImpl(
+ FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ThresholdBasedResultDiscardingRuleImpl(
new int[] { 2 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
leaderboard.addRace(testRace, "R1", /* medalRace */ false, defaultFleet);
@@ -232,7 +232,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
testRace.addCompetitor(c2);
testRace.addCompetitor(c3); // this makes maxPoints==4
ScoreCorrectionImpl scoreCorrection = new ScoreCorrectionImpl();
- FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ResultDiscardingRuleImpl(
+ FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ThresholdBasedResultDiscardingRuleImpl(
new int[] { 2 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
RaceColumn r1 = leaderboard.addRace(testRace, "R1", /* medalRace */ false, defaultFleet);
@@ -260,7 +260,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
testRaces.add(r); // hash set should take care of more or less randomly permuting the races
}
ScoreCorrectionImpl scoreCorrection = new ScoreCorrectionImpl();
- FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ResultDiscardingRuleImpl(
+ FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", scoreCorrection, new ThresholdBasedResultDiscardingRuleImpl(
new int[] { 1 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
int i=0;
@@ -287,7 +287,7 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
protected void testLeaderboard(int numberOfStartedRaces, int numberOfNotStartedRaces, int firstDiscardingThreshold,
int secondDiscardingThreshold, Integer carry, boolean addOneMedalRace, int numberOfUntrackedRaces) throws NoWindException {
setupRaces(numberOfStartedRaces, numberOfNotStartedRaces);
- FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", new ScoreCorrectionImpl(), new ResultDiscardingRuleImpl(
+ FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", new ScoreCorrectionImpl(), new ThresholdBasedResultDiscardingRuleImpl(
new int[] { firstDiscardingThreshold, secondDiscardingThreshold }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
int i=0;
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java
index bbf4f98a83f..2f3857080d1 100644
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java
@@ -45,7 +45,7 @@ import com.sap.sailing.domain.leaderboard.impl.HighPoint;
import com.sap.sailing.domain.leaderboard.impl.HighPointExtremeSailingSeriesOverall;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
-import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
+import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithStartTimeAndRanks;
@@ -60,7 +60,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
private Leaderboard createLeaderboard(Regatta regatta, int[] discardingThresholds) {
ScoreCorrectionImpl scoreCorrections = new ScoreCorrectionImpl();
- ResultDiscardingRuleImpl discardingRules = new ResultDiscardingRuleImpl(discardingThresholds);
+ ThresholdBasedResultDiscardingRuleImpl discardingRules = new ThresholdBasedResultDiscardingRuleImpl(discardingThresholds);
return new RegattaLeaderboardImpl(regatta, scoreCorrections, discardingRules);
}
@@ -801,7 +801,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
TimePoint now = MillisecondsTimePoint.now();
TimePoint later = new MillisecondsTimePoint(now.asMillis()+1000);
FlexibleLeaderboard leaderboard1 = new FlexibleLeaderboardImpl("Leaderboard 1", new ScoreCorrectionImpl(),
- new ResultDiscardingRuleImpl(/* discarding thresholds */ new int[0]), new HighPoint(), null);
+ new ThresholdBasedResultDiscardingRuleImpl(/* discarding thresholds */ new int[0]), new HighPoint(), null);
leaderboard1.addRace(new MockedTrackedRaceWithStartTimeAndRanks(now, Arrays.asList(f1)), "R1", /* medalRace */ false,
leaderboard1.getFleet(null));
leaderboard1.addRace(new MockedTrackedRaceWithStartTimeAndRanks(now, Arrays.asList(f2)), "R2", /* medalRace */ false,
@@ -809,7 +809,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
assertTrue(leaderboard1.getScoringScheme().getScoreComparator(/* nullScoresAreBetter */ false).compare(
leaderboard1.getTotalPoints(c[0], later), leaderboard1.getTotalPoints(c[3], later)) < 0); // c0 better than c3
FlexibleLeaderboard leaderboard2 = new FlexibleLeaderboardImpl("Leaderboard 3", new ScoreCorrectionImpl(),
- new ResultDiscardingRuleImpl(/* discarding thresholds */ new int[0]), new HighPoint(), null);
+ new ThresholdBasedResultDiscardingRuleImpl(/* discarding thresholds */ new int[0]), new HighPoint(), null);
leaderboard2.addRace(new MockedTrackedRaceWithStartTimeAndRanks(now, Arrays.asList(f3)), "R1", /* medalRace */ false,
leaderboard1.getFleet(null));
leaderboard2.addRace(new MockedTrackedRaceWithStartTimeAndRanks(now, Arrays.asList(f4)), "R2", /* medalRace */ false,
@@ -817,7 +817,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
assertTrue(leaderboard2.getScoringScheme().getScoreComparator(/* nullScoresAreBetter */ false).compare(
leaderboard2.getTotalPoints(c[3], later), leaderboard2.getTotalPoints(c[0], later)) < 0); // c3 better than c0
FlexibleLeaderboard leaderboard3 = new FlexibleLeaderboardImpl("Leaderboard 3", new ScoreCorrectionImpl(),
- new ResultDiscardingRuleImpl(/* discarding thresholds */ new int[0]), new HighPoint(), null);
+ new ThresholdBasedResultDiscardingRuleImpl(/* discarding thresholds */ new int[0]), new HighPoint(), null);
leaderboard3.addRace(new MockedTrackedRaceWithStartTimeAndRanks(now, Arrays.asList(f5)), "R1", /* medalRace */ false,
leaderboard1.getFleet(null));
leaderboard3.addRace(new MockedTrackedRaceWithStartTimeAndRanks(now, Arrays.asList(f6)), "R2", /* medalRace */ false,
@@ -827,7 +827,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
LeaderboardGroup leaderboardGroup = new LeaderboardGroupImpl("Leaderboard Group", "Leaderboard Group", false, Arrays.asList(leaderboard1,
leaderboard2, leaderboard3));
leaderboardGroup.setOverallLeaderboard(new LeaderboardGroupMetaLeaderboard(leaderboardGroup, new HighPointExtremeSailingSeriesOverall(),
- new ResultDiscardingRuleImpl(new int[0])));
+ new ThresholdBasedResultDiscardingRuleImpl(new int[0])));
leaderboardGroup.getOverallLeaderboard().setSuppressed(c[1], true);
leaderboardGroup.getOverallLeaderboard().setSuppressed(c[2], true);
List rankedCompetitors = leaderboardGroup.getOverallLeaderboard().getCompetitorsFromBestToWorst(later);
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java
index 38937b02c0a..d52445f78f3 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java
@@ -25,7 +25,7 @@ import com.sap.sailing.domain.base.impl.DomainFactoryImpl;
import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.impl.Util.Pair;
-import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
+import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
public class OfflineSerializationTest extends AbstractSerializationTest {
/**
@@ -81,8 +81,8 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
@Test
public void testSerializingResultDiscardingRuleImpl() throws ClassNotFoundException, IOException {
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
- ResultDiscardingRuleImpl rdri = new ResultDiscardingRuleImpl(new int[] { 5, 8 });
- ResultDiscardingRuleImpl clone = cloneBySerialization(rdri, receiverDomainFactory);
+ ThresholdBasedResultDiscardingRuleImpl rdri = new ThresholdBasedResultDiscardingRuleImpl(new int[] { 5, 8 });
+ ThresholdBasedResultDiscardingRuleImpl clone = cloneBySerialization(rdri, receiverDomainFactory);
assertTrue(Arrays.equals(rdri.getDiscardIndexResultsStartingWithHowManyRaces(),
clone.getDiscardIndexResultsStartingWithHowManyRaces()));
}
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java
index 77fad2de45a..f664e869081 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java
@@ -405,6 +405,12 @@ public class MockedTrackedRace implements DynamicTrackedRace {
public void setDefaultCourseArea(CourseArea newCourseArea) {
// TODO Auto-generated method stub
}
+
+ @Override
+ public boolean definesSeriesDiscardThresholds() {
+ // TODO Auto-generated method stub
+ return false;
+ }
};
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumnListener.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumnListener.java
index 3b5a5760c37..179ad2a790e 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumnListener.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RaceColumnListener.java
@@ -2,7 +2,7 @@ package com.sap.sailing.domain.base;
import java.io.Serializable;
-import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.tracking.TrackedRace;
@@ -26,7 +26,7 @@ public interface RaceColumnListener extends Serializable {
void competitorDisplayNameChanged(Competitor competitor, String oldDisplayName, String displayName);
- void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule, ThresholdBasedResultDiscardingRule newDiscardingRule);
+ void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule);
void raceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier, RaceLogEvent event);
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Regatta.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Regatta.java
index 72923863dfe..c2db52b48ae 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Regatta.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Regatta.java
@@ -93,4 +93,11 @@ public interface Regatta extends Named, WithID {
void addRaceColumnListener(RaceColumnListener listener);
void removeRaceColumnListener(RaceColumnListener listener);
+
+ /**
+ * @return whether this regatta defines its local per-series result discarding rules; if so, any leaderboard based
+ * on the regatta has to respect this and has to use a result discarding rule implementation that
+ * keeps discards local to each series rather than spreading them across the entire leaderboard.
+ */
+ boolean definesSeriesDiscardThresholds();
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Series.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Series.java
index cb5305a094f..039faf76289 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Series.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Series.java
@@ -1,17 +1,23 @@
package com.sap.sailing.domain.base;
+import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
/**
- * A series is a part of a {@link Regatta}. Rounds are ordered within the regatta, and rules for who is assigned to
+ * A series is a part of a {@link Regatta}. Series are ordered within the regatta, and rules for who is assigned to
* which series may exist on the regatta. For example, a regatta may have a qualification series, a final series, and a
* medal "series" with usually only a single medal race. Each series has one or more fleets, deciding how many races per
* race column have to be run in this round. For example, if the 49er regatta has so many competitors that they cannot
- * all start in one race, the qualification round can be split into two {@link Fleet}s, "Yellow" and "Blue," each
- * getting their separate races. Fleet assignment may or may not vary. This usually depends on the round's
+ * all start in one race, the qualification series can be split into two {@link Fleet}s, "Yellow" and "Blue," each
+ * getting their separate races. Fleet assignment may or may not vary. This usually depends on the series'
* characteristics of having ordered or unordered fleets.
*
+ * A series may define its result discarding scheme. If it does, a regatta leaderboard for the containing regatta
+ * has to adhere to this and may not define its own cross-cutting result discarding scheme. If one or more series
+ * in the regatta choose to define their own result discarding scheme, discards are determined per series and not
+ * per leaderboard.
+ *
* To receive notifications when {@link TrackedRace tracked races} are linked to or unlinked from any of this series'
* columns, {@link RaceColumnListener}s can be added / removed.
*
@@ -42,6 +48,14 @@ public interface Series extends SeriesBase {
void removeRaceColumn(String raceColumnName);
+ /**
+ * If not null, a containing regatta's leaderboard must obey this rule and in particular cannot define
+ * a "cross-cutting" result discarding rule where discards may be arbitrarily distributed across series.
+ */
+ ThresholdBasedResultDiscardingRule getResultDiscardingRule();
+
+ void setResultDiscardingRule(ThresholdBasedResultDiscardingRule resultDiscardingRule);
+
Regatta getRegatta();
/**
@@ -52,4 +66,11 @@ public interface Series extends SeriesBase {
void addRaceColumnListener(RaceColumnListener listener);
void removeRaceColumnListener(RaceColumnListener listener);
+
+ /**
+ * @return whether this series defines its local result discarding rule; if so, any leaderboard based on the
+ * enclosing regatta has to respect this and has to use a result discarding rule implementation that keeps
+ * discards local to each series rather than spreading them across the entire leaderboard.
+ */
+ boolean definesSeriesDiscardThresholds();
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java
index c03cd4b8e3c..f166a7bd2c4 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java
@@ -9,7 +9,6 @@ import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
-
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
@@ -24,8 +23,8 @@ import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.impl.NamedImpl;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.ScoringScheme;
-import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogStore;
@@ -302,8 +301,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
}
@Override
- public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
- ThresholdBasedResultDiscardingRule newDiscardingRule) {
+ public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
raceColumnListeners.notifyListenersAboutResultDiscardingRuleChanged(oldDiscardingRule, newDiscardingRule);
}
@@ -342,4 +340,19 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
this.defaultCourseArea = newCourseArea;
}
+ /**
+ * @return whether this regatta defines its local per-series result discarding rules; if so, any leaderboard based
+ * on the regatta has to respect this and has to use a result discarding rule implementation that
+ * keeps discards local to each series rather than spreading them across the entire leaderboard.
+ */
+ @Override
+ public boolean definesSeriesDiscardThresholds() {
+ for (Series s : series) {
+ if (s.definesSeriesDiscardThresholds()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SeriesImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SeriesImpl.java
index eec7fe7c3c2..2dd9edf5531 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SeriesImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SeriesImpl.java
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.common.impl.NamedImpl;
import com.sap.sailing.domain.common.impl.Util;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
@@ -32,6 +33,7 @@ public class SeriesImpl extends NamedImpl implements Series, RaceColumnListener
private boolean isMedal;
private Regatta regatta;
private final RaceColumnListeners raceColumnListeners;
+ private ThresholdBasedResultDiscardingRule resultDiscardingRule;
/**
* @param fleets
@@ -245,8 +247,7 @@ public class SeriesImpl extends NamedImpl implements Series, RaceColumnListener
}
@Override
- public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
- ThresholdBasedResultDiscardingRule newDiscardingRule) {
+ public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
raceColumnListeners.notifyListenersAboutResultDiscardingRuleChanged(oldDiscardingRule, newDiscardingRule);
}
@@ -259,4 +260,20 @@ public class SeriesImpl extends NamedImpl implements Series, RaceColumnListener
public boolean isTransient() {
return false;
}
+
+ @Override
+ public ThresholdBasedResultDiscardingRule getResultDiscardingRule() {
+ return resultDiscardingRule;
+ }
+
+ @Override
+ public void setResultDiscardingRule(ThresholdBasedResultDiscardingRule resultDiscardingRule) {
+ this.resultDiscardingRule = resultDiscardingRule;
+ }
+
+ @Override
+ public boolean definesSeriesDiscardThresholds() {
+ return getResultDiscardingRule() != null;
+ }
+
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java
index e86364bbe2f..682769686e9 100644
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java
@@ -282,8 +282,6 @@ public interface Leaderboard extends Named {
SettableScoreCorrection getScoreCorrection();
- ThresholdBasedResultDiscardingRule getResultDiscardingRule();
-
Competitor getCompetitorByName(String competitorName);
void setDisplayName(Competitor competitor, String displayName);
@@ -314,7 +312,19 @@ public interface Leaderboard extends Named {
*/
boolean countRaceForComparisonWithDiscardingThresholds(Competitor competitor, RaceColumn raceColumn, TimePoint timePoint);
- public void setResultDiscardingRule(ThresholdBasedResultDiscardingRule discardingRule);
+ /**
+ * Returns the result discarding rule for this leaderboard. This may be an explicit rule set for the entire leaderboard,
+ * or it may be an implicit rule that relies on other data such as a regatta's series-specific result discarding rules.
+ */
+ ResultDiscardingRule getResultDiscardingRule();
+
+ /**
+ * Trying to set a cross-leaderboard result discarding rule may fail with an exception if the leaderboard obtains
+ * its result discarding rule in another way. For example, if the leaderboard is a {@link RegattaLeaderboard} and the
+ * regatta's series define their own result discarding rules, the regatta leaderboard will use a composite
+ * result discarding rule that considers all series-specific result discarding rules.
+ */
+ public void setCrossLeaderboardResultDiscardingRule(ThresholdBasedResultDiscardingRule discardingRule);
Competitor getCompetitorByIdAsString(String idAsString);
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java
index dccab7703f0..bac500eaee8 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/LeaderboardCacheManager.java
@@ -254,8 +254,7 @@ public class LeaderboardCacheManager {
}
@Override
- public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
- ThresholdBasedResultDiscardingRule newDiscardingRule) {
+ public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
removeFromCache(leaderboard);
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java
index 24793dc6424..3e58f451118 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java
@@ -61,6 +61,7 @@ import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.NumberOfCompetitorsInLeaderboardFetcher;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.Result;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
@@ -100,7 +101,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
private final SettableScoreCorrection scoreCorrection;
- private ThresholdBasedResultDiscardingRule resultDiscardingRule;
+ private ThresholdBasedResultDiscardingRule crossLeaderboardResultDiscardingRule;
/**
* The optional display name mappings for competitors. This allows a user to override the tracking-provided
@@ -330,7 +331,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
this.carriedPoints = new HashMap();
this.scoreCorrection = scoreCorrection;
this.displayNames = new HashMap();
- this.resultDiscardingRule = resultDiscardingRule;
+ this.crossLeaderboardResultDiscardingRule = resultDiscardingRule;
this.suppressedCompetitors = Collections.synchronizedSet(new HashSet());
this.raceColumnListeners = new RaceColumnListeners();
this.raceDetailsAtEndOfTrackingCache = new HashMap, RunnableFuture>();
@@ -383,8 +384,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
}
@Override
- public ThresholdBasedResultDiscardingRule getResultDiscardingRule() {
- return resultDiscardingRule;
+ public ResultDiscardingRule getResultDiscardingRule() {
+ return crossLeaderboardResultDiscardingRule;
}
@Override
@@ -423,9 +424,9 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
}
@Override
- public void setResultDiscardingRule(ThresholdBasedResultDiscardingRule discardingRule) {
- ThresholdBasedResultDiscardingRule oldDiscardingRule = getResultDiscardingRule();
- this.resultDiscardingRule = discardingRule;
+ public void setCrossLeaderboardResultDiscardingRule(ThresholdBasedResultDiscardingRule discardingRule) {
+ ResultDiscardingRule oldDiscardingRule = getResultDiscardingRule();
+ this.crossLeaderboardResultDiscardingRule = discardingRule;
getRaceColumnListeners().notifyListenersAboutResultDiscardingRuleChanged(oldDiscardingRule, discardingRule);
}
@@ -735,8 +736,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
}
@Override
- public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
- ThresholdBasedResultDiscardingRule newDiscardingRule) {
+ public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
getRaceColumnListeners().notifyListenersAboutResultDiscardingRuleChanged(oldDiscardingRule, newDiscardingRule);
}
@@ -1021,7 +1021,11 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
result.setDelayToLiveInMillisForLatestRace(this.getDelayToLiveInMillis());
result.rows = new HashMap();
result.hasCarriedPoints = this.hasCarriedPoints();
- result.discardThresholds = this.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces();
+ if (this.getResultDiscardingRule() instanceof ThresholdBasedResultDiscardingRule) {
+ result.discardThresholds = ((ThresholdBasedResultDiscardingRule) this.getResultDiscardingRule()).getDiscardIndexResultsStartingWithHowManyRaces();
+ } else {
+ result.discardThresholds = null;
+ }
// Computing the competitor leg ranks is expensive, especially in live mode, in case new events keep invalidating
// the ranks cache in TrackedLegImpl. Then problem then is that the sorting based on wind data is repeated for each
// competitor, leading to square effort. We therefore need to compute the leg ranks for those race where leg details
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/PerSeriesResultDiscardingRuleImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/PerSeriesResultDiscardingRuleImpl.java
new file mode 100755
index 00000000000..5b3c2522762
--- /dev/null
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/PerSeriesResultDiscardingRuleImpl.java
@@ -0,0 +1,55 @@
+package com.sap.sailing.domain.leaderboard.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.sap.sailing.domain.base.Competitor;
+import com.sap.sailing.domain.base.RaceColumn;
+import com.sap.sailing.domain.base.Regatta;
+import com.sap.sailing.domain.base.Series;
+import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.common.impl.Util;
+import com.sap.sailing.domain.leaderboard.Leaderboard;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
+
+/**
+ * A result discarding rule that is used when one or more of a {@link Regatta}'s {@link Series} define their own
+ * result discarding rule. In this case, discards are decided per series and not per regatta or leaderboard.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class PerSeriesResultDiscardingRuleImpl implements ResultDiscardingRule {
+ private static final long serialVersionUID = 4596442640424592181L;
+
+ private final Regatta regatta;
+
+ public PerSeriesResultDiscardingRuleImpl(Regatta regatta) {
+ super();
+ this.regatta = regatta;
+ }
+
+ @Override
+ public Set getDiscardedRaceColumns(Competitor competitor, Leaderboard leaderboard,
+ Iterable raceColumnsToConsider, TimePoint timePoint) {
+ Set result = new HashSet<>();
+ for (Series s : regatta.getSeries()) {
+ if (s.getResultDiscardingRule() != null) {
+ Iterable columnsToConsiderInSeries = getColumnsToConsiderInSeries(s, raceColumnsToConsider);
+ result.addAll(s.getResultDiscardingRule().getDiscardedRaceColumns(competitor, leaderboard, columnsToConsiderInSeries, timePoint));
+ }
+ }
+ return result;
+ }
+
+ private Iterable getColumnsToConsiderInSeries(Series series, Iterable allRaceColumnsToConsider) {
+ Set result = new HashSet<>();
+ for (RaceColumn seriesColumn : series.getRaceColumns()) {
+ if (Util.contains(allRaceColumnsToConsider, seriesColumn)) {
+ result.add(seriesColumn);
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java
index 8e3725f45ea..02439785dd1 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.RaceColumnInSeriesImpl;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
@@ -81,4 +82,21 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
return regatta.getDefaultCourseArea();
}
+ /**
+ * If the regatta' series {@link Regatta#definesSeriesDiscardThresholds() define} their own result discarding rules, this leaderboard uses
+ * a composite result discarding rule of type {@link PerSeriesResultDiscardingRuleImpl} that contains discards within each series according
+ * to the series' discarding rules. Otherwise, the default cross-leaderboard result discarding rule is obtained from the super class
+ * implementation.
+ */
+ @Override
+ public ResultDiscardingRule getResultDiscardingRule() {
+ if (regatta.definesSeriesDiscardThresholds()) {
+ return new PerSeriesResultDiscardingRuleImpl(regatta);
+ } else {
+ return super.getResultDiscardingRule();
+ }
+ }
+
+
+
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ResultDiscardingRuleImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ThresholdBasedResultDiscardingRuleImpl.java
similarity index 94%
rename from java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ResultDiscardingRuleImpl.java
rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ThresholdBasedResultDiscardingRuleImpl.java
index 71947814eef..68b0c137171 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ResultDiscardingRuleImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/ThresholdBasedResultDiscardingRuleImpl.java
@@ -30,11 +30,11 @@ import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
* @author Axel Uhl (d043530)
*
*/
-public class ResultDiscardingRuleImpl implements ThresholdBasedResultDiscardingRule {
+public class ThresholdBasedResultDiscardingRuleImpl implements ThresholdBasedResultDiscardingRule {
private static final long serialVersionUID = 386341628517357988L;
private final int[] discardIndexResultsStartingWithHowManyRaces;
- public ResultDiscardingRuleImpl(int[] discardIndexResultsStartingWithHowManyRaces) {
+ public ThresholdBasedResultDiscardingRuleImpl(int[] discardIndexResultsStartingWithHowManyRaces) {
super();
this.discardIndexResultsStartingWithHowManyRaces = new int[discardIndexResultsStartingWithHowManyRaces.length];
System.arraycopy(discardIndexResultsStartingWithHowManyRaces, 0,
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java
index 379c7482274..1318168f910 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java
@@ -9,7 +9,7 @@ import com.sap.sailing.domain.base.RaceColumnListener;
import com.sap.sailing.domain.base.impl.SimpleAbstractRaceColumn;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.leaderboard.Leaderboard;
-import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
@@ -152,8 +152,7 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R
}
@Override
- public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
- ThresholdBasedResultDiscardingRule newDiscardingRule) {
+ public void resultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule, ResultDiscardingRule newDiscardingRule) {
getRaceColumnListeners().notifyListenersAboutResultDiscardingRuleChanged(oldDiscardingRule, newDiscardingRule);
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/util/impl/RaceColumnListeners.java b/java/com.sap.sailing.domain/src/com/sap/sailing/util/impl/RaceColumnListeners.java
index e1d8137e277..ffb08c1d681 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/util/impl/RaceColumnListeners.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/util/impl/RaceColumnListeners.java
@@ -11,7 +11,7 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceColumnListener;
-import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
+import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.tracking.TrackedRace;
@@ -126,8 +126,8 @@ public class RaceColumnListeners implements Serializable {
}
}
- public void notifyListenersAboutResultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
- ThresholdBasedResultDiscardingRule newDiscardingRule) {
+ public void notifyListenersAboutResultDiscardingRuleChanged(ResultDiscardingRule oldDiscardingRule,
+ ResultDiscardingRule newDiscardingRule) {
for (RaceColumnListener listener : getRaceColumnListeners()) {
listener.resultDiscardingRuleChanged(oldDiscardingRule, newDiscardingRule);
}
diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java
index 0297d62bc68..3c2bfb860a5 100644
--- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java
+++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java
@@ -406,6 +406,12 @@ public class MockedTrackedRace implements DynamicTrackedRace {
// TODO Auto-generated method stub
}
+
+ @Override
+ public boolean definesSeriesDiscardThresholds() {
+ // TODO Auto-generated method stub
+ return false;
+ }
};
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractLeaderboardDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractLeaderboardDialog.java
index 58550481ecd..401a98dc781 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractLeaderboardDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractLeaderboardDialog.java
@@ -1,10 +1,6 @@
package com.sap.sailing.gwt.ui.adminconsole;
-import java.util.ArrayList;
-import java.util.List;
-
import com.google.gwt.user.client.ui.ListBox;
-import com.google.gwt.user.client.ui.LongBox;
import com.google.gwt.user.client.ui.TextBox;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.gwt.ui.client.DataEntryDialog;
@@ -17,73 +13,30 @@ public abstract class AbstractLeaderboardDialog extends DataEntryDialog validator, DialogCallback callback) {
- super(title, null, stringConstants.ok(), stringConstants.cancel(), validator, callback);
- this.stringMessages = stringConstants;
+ super(title, null, stringMessages.ok(), stringMessages.cancel(), validator, callback);
+ this.stringMessages = stringMessages;
this.leaderboardDescriptor = leaderboardDescriptor;
}
@Override
protected LeaderboardDescriptor getResult() {
- int[] discardThresholdsBoxContents = getDiscardThresholds(discardThresholdBoxes);
leaderboardDescriptor.setName(nameTextBox.getValue());
leaderboardDescriptor.setDisplayName(displayNameTextBox.getValue().trim().isEmpty() ? null : displayNameTextBox.getValue());
- leaderboardDescriptor.setDiscardThresholds(discardThresholdsBoxContents);
+ leaderboardDescriptor.setDiscardThresholds(discardThresholdBoxes==null?null:discardThresholdBoxes.getDiscardThresholds());
return leaderboardDescriptor;
}
- protected static int[] getDiscardThresholds(LongBox[] discardThresholdBoxes) {
- List discardThresholds = new ArrayList();
- // go backwards; starting from first non-zero element, add them; take over leading zeroes which validator shall discard
- for (int i = discardThresholdBoxes.length-1; i>=0; i--) {
- if ((discardThresholdBoxes[i].getValue() != null
- && discardThresholdBoxes[i].getValue().toString().length() > 0) || !discardThresholds.isEmpty()) {
- if (discardThresholdBoxes[i].getValue() == null) {
- discardThresholds.add(0, 0);
- } else {
- discardThresholds.add(0, discardThresholdBoxes[i].getValue().intValue());
- }
- }
- }
- int[] discardThresholdsBoxContents = new int[discardThresholds.size()];
- for (int i = 0; i < discardThresholds.size(); i++) {
- discardThresholdsBoxContents[i] = discardThresholds.get(i);
- }
- return discardThresholdsBoxContents;
- }
-
@Override
public void show() {
super.show();
nameTextBox.setFocus(true);
}
- protected static LongBox[] initEmptyDiscardThresholdBoxes(DataEntryDialog> dialog) {
- LongBox[] result = new LongBox[MAX_NUMBER_OF_DISCARDED_RESULTS];
- for (int i = 0; i < result.length; i++) {
- result[i] = dialog.createLongBoxWithOptionalValue(null, 2);
- result[i].setVisibleLength(2);
- }
- return result;
- }
-
- protected static LongBox[] initPrefilledDiscardThresholdBoxes(int[] valuesToShow, DataEntryDialog> dialog) {
- LongBox[] result = new LongBox[MAX_NUMBER_OF_DISCARDED_RESULTS];
- for (int i = 0; i < result.length; i++) {
- if (i < valuesToShow.length) {
- result[i] = dialog.createLongBox(valuesToShow[i], 2);
- } else {
- result[i] = dialog.createLongBoxWithOptionalValue(null, 2);
- }
- result[i].setVisibleLength(2);
- }
- return result;
- }
-
protected static ListBox createScoringSchemeListBox(DataEntryDialog> dialog, StringMessages stringMessages) {
ListBox scoringSchemeListBox2 = dialog.createListBox(false);
for (ScoringSchemeType scoringSchemeType: ScoringSchemeType.values()) {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DiscardThresholdBoxes.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DiscardThresholdBoxes.java
new file mode 100755
index 00000000000..0e6b3730115
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DiscardThresholdBoxes.java
@@ -0,0 +1,116 @@
+package com.sap.sailing.gwt.ui.adminconsole;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.LongBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.sap.sailing.gwt.ui.client.DataEntryDialog;
+import com.sap.sailing.gwt.ui.client.StringMessages;
+
+/**
+ * For a result discarding rule based on thresholds that tell after how many races the next discard kicks in, an instance of
+ * this class offers the UI components and validation rules that help in composing a UI that, among other things, allows a user
+ * to configure the discarding thresholds.
+ *
+ * TODO produce error messages during validation
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class DiscardThresholdBoxes {
+ private static final int MAX_NUMBER_OF_DISCARDED_RESULTS = 4;
+
+ private final LongBox[] discardThresholdBoxes;
+ private final DataEntryDialog> parent;
+
+ /**
+ * The widget used to represent the UI
+ */
+ private final Widget widget;
+
+ public DiscardThresholdBoxes(DataEntryDialog> parent, StringMessages stringMessages) {
+ this(parent, /* values to show */ new int[0], stringMessages);
+ }
+
+ public DiscardThresholdBoxes(DataEntryDialog> parent, int[] initialDiscardThresholds, StringMessages stringMessages) {
+ this.parent = parent;
+ discardThresholdBoxes = new LongBox[MAX_NUMBER_OF_DISCARDED_RESULTS];
+ for (int i = 0; i < discardThresholdBoxes.length; i++) {
+ if (initialDiscardThresholds != null && i < initialDiscardThresholds.length) {
+ discardThresholdBoxes[i] = parent.createLongBox(initialDiscardThresholds[i], 2);
+ } else {
+ discardThresholdBoxes[i] = parent.createLongBoxWithOptionalValue(null, 2);
+ }
+ discardThresholdBoxes[i].setVisibleLength(2);
+ }
+ widget = createDiscardThresholdBoxesPanel(stringMessages);
+ }
+
+ /**
+ * @return the widget that can be added to the parent dialog passed to the constructor to visualize and edit the
+ * result discarding thresholds. The result returned from this object remains the same across this object's
+ * life time.
+ */
+ public Widget getWidget() {
+ return widget;
+ }
+
+ public int[] getDiscardThresholds() {
+ List discardThresholds = new ArrayList();
+ // go backwards; starting from first non-zero element, add them; take over leading zeroes which validator shall discard
+ for (int i = discardThresholdBoxes.length-1; i>=0; i--) {
+ if ((discardThresholdBoxes[i].getValue() != null
+ && discardThresholdBoxes[i].getValue().toString().length() > 0) || !discardThresholds.isEmpty()) {
+ if (discardThresholdBoxes[i].getValue() == null) {
+ discardThresholds.add(0, 0);
+ } else {
+ discardThresholds.add(0, discardThresholdBoxes[i].getValue().intValue());
+ }
+ }
+ }
+ int[] discardThresholdsBoxContents = new int[discardThresholds.size()];
+ for (int i = 0; i < discardThresholds.size(); i++) {
+ discardThresholdsBoxContents[i] = discardThresholds.get(i);
+ }
+ return discardThresholdsBoxContents;
+ }
+
+ private Widget createDiscardThresholdBoxesPanel(StringMessages stringMessages) {
+ assert discardThresholdBoxes != null && discardThresholdBoxes.length == MAX_NUMBER_OF_DISCARDED_RESULTS;
+ VerticalPanel vp = new VerticalPanel();
+ vp.add(new Label(stringMessages.discardRacesFromHowManyStartedRacesOn()));
+ HorizontalPanel hp = new HorizontalPanel();
+ vp.add(hp);
+ hp.setSpacing(3);
+ for (int i = 0; i < discardThresholdBoxes.length; i++) {
+ hp.add(new Label("" + (i + 1) + "."));
+ hp.add(discardThresholdBoxes[i]);
+ }
+ parent.alignAllPanelWidgetsVertically(hp, HasVerticalAlignment.ALIGN_MIDDLE);
+ return vp;
+ }
+
+ public static String getErrorMessage(int[] discardThresholds, StringMessages stringMessages) {
+ String errorMessage = null;
+ if (discardThresholds != null) {
+ boolean discardThresholdsAscending = true;
+ for (int i = 1; i < discardThresholds.length; i++) {
+ if (0 < discardThresholds.length) {
+ discardThresholdsAscending = discardThresholdsAscending
+ && discardThresholds[i - 1] < discardThresholds[i]
+ // and if one box is empty, all subsequent boxes need to be empty too
+ && (discardThresholds[i] == 0 || discardThresholds[i - 1] > 0);
+ }
+ }
+ if (!discardThresholdsAscending) {
+ errorMessage = stringMessages.discardThresholdsMustBeAscending();
+ }
+ }
+ return errorMessage;
+ }
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardCreateDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardCreateDialog.java
index 88d89470fbd..dbf454bfae2 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardCreateDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardCreateDialog.java
@@ -11,7 +11,8 @@ public class FlexibleLeaderboardCreateDialog extends FlexibleLeaderboardDialog {
public FlexibleLeaderboardCreateDialog(Collection existingLeaderboards, StringMessages stringMessages,
Collection existingEvents, ErrorReporter errorReporter, DialogCallback callback) {
- super(stringMessages.createFlexibleLeaderboard(), new LeaderboardDescriptor(), stringMessages, existingEvents, errorReporter, new FlexibleLeaderboardDialog.LeaderboardParameterValidator(stringMessages, existingLeaderboards), callback);
+ super(stringMessages.createFlexibleLeaderboard(), new LeaderboardDescriptor(), stringMessages, existingEvents,
+ errorReporter, new FlexibleLeaderboardDialog.LeaderboardParameterValidator(stringMessages, existingLeaderboards), callback);
nameTextBox = createTextBox(null);
nameTextBox.ensureDebugId("LeaderboardNameField");
displayNameTextBox = createTextBox(null);
@@ -20,6 +21,6 @@ public class FlexibleLeaderboardCreateDialog extends FlexibleLeaderboardDialog {
scoringSchemeListBox = createScoringSchemeListBox(this, stringMessages);
sailingEventsListBox = createSailingEventListBox();
- discardThresholdBoxes = initEmptyDiscardThresholdBoxes(this);
+ discardThresholdBoxes = new DiscardThresholdBoxes(this, stringMessages);
}
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardDialog.java
index 0ba615592d0..d55ad914d4f 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardDialog.java
@@ -6,8 +6,6 @@ import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.HasVerticalAlignment;
-import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
@@ -24,12 +22,12 @@ public abstract class FlexibleLeaderboardDialog extends AbstractLeaderboardDialo
protected ListBox courseAreaListBox;
protected static class LeaderboardParameterValidator implements Validator {
- protected final StringMessages stringConstants;
+ protected final StringMessages stringMessages;
protected final Collection existingLeaderboards;
- public LeaderboardParameterValidator(StringMessages stringConstants, Collection existingLeaderboards){
+ public LeaderboardParameterValidator(StringMessages stringConstants, Collection existingLeaderboards) {
super();
- this.stringConstants = stringConstants;
+ this.stringMessages = stringConstants;
this.existingLeaderboards = existingLeaderboards;
}
@@ -37,33 +35,23 @@ public abstract class FlexibleLeaderboardDialog extends AbstractLeaderboardDialo
public String getErrorMessage(LeaderboardDescriptor leaderboardToValidate) {
String errorMessage;
boolean nonEmpty = leaderboardToValidate.getName() != null && leaderboardToValidate.getName().length() > 0;
-
- boolean discardThresholdsAscending = true;
- for (int i = 1; i < leaderboardToValidate.getDiscardThresholds().length; i++) {
- // TODO what are correct values for discarding Thresholds?
- if (0 < leaderboardToValidate.getDiscardThresholds().length){
- discardThresholdsAscending = discardThresholdsAscending
- && leaderboardToValidate.getDiscardThresholds()[i - 1] < leaderboardToValidate.getDiscardThresholds()[i]
- // and if one box is empty, all subsequent boxes need to be empty too
- && (leaderboardToValidate.getDiscardThresholds()[i] == 0 || leaderboardToValidate.getDiscardThresholds()[i-1] > 0);
- }
- }
-
boolean unique = true;
for (StrippedLeaderboardDTO dao : existingLeaderboards) {
if(dao.name.equals(leaderboardToValidate.getName())){
unique = false;
}
}
-
if (!nonEmpty) {
- errorMessage = stringConstants.pleaseEnterAName();
+ errorMessage = stringMessages.pleaseEnterAName();
} else if(!unique){
- errorMessage = stringConstants.leaderboardWithThisNameAlreadyExists();
- } else if (!discardThresholdsAscending) {
- errorMessage = stringConstants.discardThresholdsMustBeAscending();
+ errorMessage = stringMessages.leaderboardWithThisNameAlreadyExists();
} else {
- errorMessage = null;
+ String discardThresholdErrorMessage = DiscardThresholdBoxes.getErrorMessage(leaderboardToValidate.getDiscardThresholds(), stringMessages);
+ if (discardThresholdErrorMessage != null) {
+ errorMessage = discardThresholdErrorMessage;
+ } else {
+ errorMessage = null;
+ }
}
return errorMessage;
}
@@ -112,15 +100,7 @@ public abstract class FlexibleLeaderboardDialog extends AbstractLeaderboardDialo
formGrid.setWidget(4, 0, new Label(stringMessages.courseArea() + ":"));
formGrid.setWidget(4, 1, courseAreaListBox);
mainPanel.add(formGrid);
- mainPanel.add(new Label(stringMessages.discardRacesFromHowManyStartedRacesOn()));
- HorizontalPanel hp = new HorizontalPanel();
- hp.setSpacing(3);
- for (int i = 0; i < discardThresholdBoxes.length; i++) {
- hp.add(new Label("" + (i + 1) + "."));
- hp.add(discardThresholdBoxes[i]);
- }
- alignAllPanelWidgetsVertically(hp, HasVerticalAlignment.ALIGN_MIDDLE);
- mainPanel.add(hp);
+ mainPanel.add(discardThresholdBoxes.getWidget());
return mainPanel;
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardEditDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardEditDialog.java
index 20c717f4416..f182de91b50 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardEditDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardEditDialog.java
@@ -14,10 +14,10 @@ import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
public class FlexibleLeaderboardEditDialog extends FlexibleLeaderboardDialog {
public FlexibleLeaderboardEditDialog(Collection otherExistingLeaderboards,
- LeaderboardDescriptor leaderboard, StringMessages stringConstants, List existingEvents, ErrorReporter errorReporter,
+ LeaderboardDescriptor leaderboard, StringMessages stringMessages, List existingEvents, ErrorReporter errorReporter,
DialogCallback callback) {
- super(stringConstants.editFlexibleLeaderboard(), leaderboard, stringConstants, existingEvents, errorReporter, new FlexibleLeaderboardDialog.LeaderboardParameterValidator(
- stringConstants, otherExistingLeaderboards), callback);
+ super(stringMessages.editFlexibleLeaderboard(), leaderboard, stringMessages, existingEvents, errorReporter, new FlexibleLeaderboardDialog.LeaderboardParameterValidator(
+ stringMessages, otherExistingLeaderboards), callback);
nameTextBox = createTextBox(leaderboard.getName());
displayNameTextBox = createTextBox(leaderboard.getDisplayName());
@@ -27,7 +27,7 @@ public class FlexibleLeaderboardEditDialog extends FlexibleLeaderboardDialog {
int j = 0;
for (ScoringSchemeType scoringSchemeType: ScoringSchemeType.values()) {
- scoringSchemeListBox.addItem(ScoringSchemeTypeFormatter.format(scoringSchemeType, stringConstants));
+ scoringSchemeListBox.addItem(ScoringSchemeTypeFormatter.format(scoringSchemeType, stringMessages));
if(leaderboard.getScoringScheme() == scoringSchemeType) {
scoringSchemeListBox.setSelectedIndex(j);
}
@@ -48,6 +48,6 @@ public class FlexibleLeaderboardEditDialog extends FlexibleLeaderboardDialog {
}
}
}
- discardThresholdBoxes = initPrefilledDiscardThresholdBoxes(leaderboard.getDiscardThresholds(), this);
+ discardThresholdBoxes = new DiscardThresholdBoxes(this, leaderboard.getDiscardThresholds(), stringMessages);
}
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java
index 43b8d0c0841..c5976537bb7 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java
@@ -269,8 +269,10 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
Window.alert("This is a meta leaderboard. It can't be changed here.");
} else {
if (leaderboardDTO.isRegattaLeaderboard) {
- LeaderboardDescriptor descriptor = new LeaderboardDescriptor(leaderboardDTO.name,
- leaderboardDTO.displayName, null, leaderboardDTO.discardThresholds, leaderboardDTO.regattaName, leaderboardDTO.defaultCourseAreaIdAsString);
+ LeaderboardDescriptor descriptor = new LeaderboardDescriptor(leaderboardDTO.name,
+ leaderboardDTO.displayName, /* scoring scheme provided by regatta */ null,
+ leaderboardDTO.discardThresholds, leaderboardDTO.regattaName,
+ leaderboardDTO.defaultCourseAreaIdAsString);
AbstractLeaderboardDialog dialog = new RegattaLeaderboardEditDialog(Collections
.unmodifiableCollection(otherExistingLeaderboard), Collections.unmodifiableCollection(allRegattas),
descriptor, stringMessages, errorReporter,
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardDescriptor.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardDescriptor.java
index dcd8816e882..1acdb0ce128 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardDescriptor.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardDescriptor.java
@@ -3,9 +3,10 @@ package com.sap.sailing.gwt.ui.adminconsole;
import com.sap.sailing.domain.common.ScoringSchemeType;
/**
- * A descriptor class for creating and editing basic data of a leaderboard
+ * A descriptor class for creating and editing basic data of a leaderboard.
+ *
* @author Frank
- *
+ *
*/
public class LeaderboardDescriptor {
private String name;
@@ -27,6 +28,9 @@ public class LeaderboardDescriptor {
this.courseAreaIdAsString = courseAreaIdAsString;
}
+ /**
+ * Leaves the {@link #regattaName} null, representing a flexible leaderboard, not a regatta leaderboard
+ */
public LeaderboardDescriptor(String name, String displayName, ScoringSchemeType scoringScheme, int[] discardThresholds, String courseAreaIdAsString) {
this.name = name;
this.displayName = displayName;
@@ -51,6 +55,11 @@ public class LeaderboardDescriptor {
this.scoringScheme = scoringScheme;
}
+ /**
+ * @return null, in case the leaderboard does not explicitly define result discarding thresholds itself
+ * (e.g., a regatta leaderboard that obtains its result discarding rules from the underlying regatta's
+ * series definitions); a valid but possibly empty array otherwise
+ */
public int[] getDiscardThresholds() {
return discardThresholds;
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupDialog.java
index 93e0b2003a5..b1a3e74fd20 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupDialog.java
@@ -10,10 +10,8 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
-import com.google.gwt.user.client.ui.LongBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
@@ -32,7 +30,7 @@ public class LeaderboardGroupDialog extends DataEntryDialog callback, Collection existingLeaderboardGroups) {
super(stringMessages.leaderboardGroup(), null, stringMessages.ok(), stringMessages.cancel(),
@@ -140,20 +134,12 @@ public class LeaderboardGroupDialog extends DataEntryDialog();
seriesSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@@ -96,11 +88,9 @@ public class RegattaDetailsComposite extends Composite {
}
});
seriesTable.setSelectionModel(seriesSelectionModel);
-
seriesListDataProvider = new ListDataProvider();
seriesListDataProvider.addDataDisplay(seriesTable);
vPanel.add(seriesTable);
-
initWidget(mainPanel);
}
@@ -161,6 +151,29 @@ public class RegattaDetailsComposite extends Composite {
}
};
+ TextColumn discardsColumn = new TextColumn() {
+ @Override
+ public String getValue(SeriesDTO series) {
+ final String result;
+ if (series.getDiscardThresholds() == null) {
+ result = stringMessages.no();
+ } else {
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (int threshold : series.getDiscardThresholds()) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(", ");
+ }
+ sb.append(threshold);
+ }
+ result = sb.toString();
+ }
+ return result;
+ }
+ };
+
ImagesBarColumn seriesActionColumn = new ImagesBarColumn(
new SeriesConfigImagesBarCell(stringMessages));
seriesActionColumn.setFieldUpdater(new FieldUpdater() {
@@ -179,6 +192,7 @@ public class RegattaDetailsComposite extends Composite {
table.addColumn(isMedalSeriesColumn, stringMessages.medalSeries());
table.addColumn(racesColumn, stringMessages.races());
table.addColumn(fleetsColumn, stringMessages.fleets());
+ table.addColumn(discardsColumn, stringMessages.discarding());
table.addColumn(seriesActionColumn, stringMessages.actions());
return table;
@@ -194,21 +208,26 @@ public class RegattaDetailsComposite extends Composite {
}
private void editRacesOfRegattaSeries(final RegattaDTO regatta, final SeriesDTO series) {
- RaceColumnInRegattaSeriesDialog raceDialog = new RaceColumnInRegattaSeriesDialog(regatta, series, stringMessages,
- new DialogCallback>>() {
+ SeriesEditDialog raceDialog = new SeriesEditDialog(regatta, series, stringMessages,
+ new DialogCallback() {
@Override
public void cancel() {
}
@Override
- public void ok(final Pair> result) {
- updateRacesOfRegattaSeries(regatta, result.getA(), result.getB());
+ public void ok(final SeriesDescriptor result) {
+ updateRacesOfRegattaSeries(regatta, result);
}
});
raceDialog.show();
}
- private void updateRacesOfRegattaSeries(final RegattaDTO regatta, final SeriesDTO series, List newRaceColumns) {
+ private void updateRacesOfRegattaSeries(final RegattaDTO regatta, final SeriesDescriptor seriesDescriptor) {
+ final SeriesDTO series = seriesDescriptor.getSeries();
+ final List newRaceColumns = seriesDescriptor.getRaces();
+ final boolean isMedalChanged = series.isMedal() != seriesDescriptor.isMedal();
+ final boolean seriesResultDiscardingThresholdsChanged = !Arrays.equals(series.getDiscardThresholds(),
+ seriesDescriptor.getResultDiscardingThresholds());
final RegattaIdentifier regattaIdentifier = new RegattaName(regatta.name);
List existingRaceColumns = series.getRaceColumns();
final List raceColumnsToAdd = new ArrayList();
@@ -224,7 +243,6 @@ public class RegattaDetailsComposite extends Composite {
raceColumnsToRemove.add(existingRaceColumn.name);
}
}
-
sailingService.addRaceColumnsToSeries(regattaIdentifier, series.name, raceColumnsToAdd, new AsyncCallback>() {
@Override
public void onFailure(Throwable caught) {
@@ -246,7 +264,6 @@ public class RegattaDetailsComposite extends Composite {
errorReporter.reportError("Error trying to remove race columns "
+ raceColumnsToAdd + " from series " + series.name
+ ": " + caught.getMessage());
-
}
@Override
@@ -254,6 +271,22 @@ public class RegattaDetailsComposite extends Composite {
regattaRefresher.fillRegattas();
}
});
+ if (isMedalChanged || seriesResultDiscardingThresholdsChanged) {
+ sailingService.updateSeries(regattaIdentifier, series.name, seriesDescriptor.isMedal(),
+ seriesDescriptor.getResultDiscardingThresholds(), new AsyncCallback() {
+ @Override
+ public void onFailure(Throwable caught) {
+ errorReporter.reportError("Error trying to remove race columns "
+ + raceColumnsToAdd + " from series " + series.name
+ + ": " + caught.getMessage());
+ }
+
+ @Override
+ public void onSuccess(Void result) {
+ regattaRefresher.fillRegattas();
+ }
+ });
+ }
}
private void updateRegattaDetails() {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardCreateDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardCreateDialog.java
index ccb46a445da..49dbfcf9637 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardCreateDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardCreateDialog.java
@@ -11,9 +11,9 @@ import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
public class RegattaLeaderboardCreateDialog extends RegattaLeaderboardDialog {
- public RegattaLeaderboardCreateDialog(Collection existingLeaderboards, Collection existingRegattas, StringMessages stringConstants,
+ public RegattaLeaderboardCreateDialog(Collection existingLeaderboards, Collection existingRegattas, StringMessages stringMessages,
ErrorReporter errorReporter, DialogCallback callback) {
- super(stringConstants.createRegattaLeaderboard(), new LeaderboardDescriptor(), existingRegattas, stringConstants, errorReporter, new RegattaLeaderboardDialog.LeaderboardParameterValidator(stringConstants, existingLeaderboards), callback);
+ super(stringMessages.createRegattaLeaderboard(), new LeaderboardDescriptor(), existingRegattas, stringMessages, errorReporter, new RegattaLeaderboardDialog.LeaderboardParameterValidator(stringMessages, existingLeaderboards), callback);
nameTextBox = createTextBox(null);
displayNameTextBox = createTextBox(null);
@@ -30,11 +30,10 @@ public class RegattaLeaderboardCreateDialog extends RegattaLeaderboardDialog {
if (selectedIndex > 0) {
nameTextBox.setText(regattaListBox.getValue(selectedIndex));
}
+ adjustVisibilityOfResultDiscardingRuleComponent();
}
});
-
-
- discardThresholdBoxes = initEmptyDiscardThresholdBoxes(this);
+ discardThresholdBoxes = new DiscardThresholdBoxes(this, stringMessages);
}
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardDialog.java
index df98cb6930c..095d844acbb 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardDialog.java
@@ -6,8 +6,6 @@ import java.util.Collections;
import java.util.List;
import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.HasVerticalAlignment;
-import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
@@ -21,58 +19,62 @@ import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
public abstract class RegattaLeaderboardDialog extends AbstractLeaderboardDialog {
protected ListBox regattaListBox;
protected Collection existingRegattas;
+ private Label regattaDefinesDiscardsLabel;
protected static class LeaderboardParameterValidator implements Validator {
- protected final StringMessages stringConstants;
+ protected final StringMessages stringMessages;
protected final Collection existingLeaderboards;
- public LeaderboardParameterValidator(StringMessages stringConstants, Collection existingLeaderboards){
+ public LeaderboardParameterValidator(StringMessages stringMessages, Collection existingLeaderboards){
super();
- this.stringConstants = stringConstants;
+ this.stringMessages = stringMessages;
this.existingLeaderboards = existingLeaderboards;
}
@Override
public String getErrorMessage(LeaderboardDescriptor leaderboardToValidate) {
String errorMessage;
-
- boolean discardThresholdsAscending = true;
- for (int i = 1; i < leaderboardToValidate.getDiscardThresholds().length; i++) {
- // TODO what are correct values for discarding Thresholds?
- if (0 < leaderboardToValidate.getDiscardThresholds().length){
- discardThresholdsAscending = discardThresholdsAscending
- && leaderboardToValidate.getDiscardThresholds()[i - 1] < leaderboardToValidate.getDiscardThresholds()[i]
- // and if one box is empty, all subsequent boxes need to be empty too
- && (leaderboardToValidate.getDiscardThresholds()[i] == 0 || leaderboardToValidate.getDiscardThresholds()[i-1] > 0);
- }
- }
-
boolean unique = true;
for (StrippedLeaderboardDTO dao : existingLeaderboards) {
if(dao.name.equals(leaderboardToValidate.getRegattaName())){
unique = false;
}
}
-
boolean regattaSelected = leaderboardToValidate.getRegattaName() != null ? true : false;
if(!regattaSelected){
- errorMessage = stringConstants.pleaseSelectARegatta();
+ errorMessage = stringMessages.pleaseSelectARegatta();
} else if(!unique){
- errorMessage = stringConstants.leaderboardWithThisNameAlreadyExists();
- } else if (!discardThresholdsAscending) {
- errorMessage = stringConstants.discardThresholdsMustBeAscending();
+ errorMessage = stringMessages.leaderboardWithThisNameAlreadyExists();
} else {
- errorMessage = null;
+ String discardThresholdErrorMessage = DiscardThresholdBoxes.getErrorMessage(
+ leaderboardToValidate.getDiscardThresholds(), stringMessages);
+ if (discardThresholdErrorMessage != null) {
+ errorMessage = discardThresholdErrorMessage;
+ } else {
+ errorMessage = null;
+ }
}
return errorMessage;
}
}
- public RegattaLeaderboardDialog(String title, LeaderboardDescriptor leaderboardDTO, Collection existingRegattas, StringMessages stringConstants,
+ public RegattaLeaderboardDialog(String title, LeaderboardDescriptor leaderboardDTO, Collection existingRegattas, StringMessages stringMessages,
ErrorReporter errorReporter, LeaderboardParameterValidator validator, DialogCallback callback) {
- super(title, leaderboardDTO, stringConstants, validator, callback);
+ super(title, leaderboardDTO, stringMessages, validator, callback);
this.existingRegattas = existingRegattas;
+ regattaDefinesDiscardsLabel = new Label(stringMessages.regattaDefinesResultDiscardingRules());
+ }
+
+
+ protected void adjustVisibilityOfResultDiscardingRuleComponent() {
+ if (getSelectedRegatta().definesSeriesDiscardThresholds()) {
+ discardThresholdBoxes.getWidget().setVisible(false);
+ regattaDefinesDiscardsLabel.setVisible(true);
+ } else {
+ discardThresholdBoxes.getWidget().setVisible(true);
+ regattaDefinesDiscardsLabel.setVisible(false);
+ }
}
protected ListBox createSortedRegattaListBox(Collection regattas, String preSelectedRegattaName) {
@@ -107,7 +109,6 @@ public abstract class RegattaLeaderboardDialog extends AbstractLeaderboardDialog
@Override
protected Widget getAdditionalWidget() {
VerticalPanel mainPanel = new VerticalPanel();
-
Grid formGrid = new Grid(3,3);
formGrid.setCellSpacing(3);
formGrid.setWidget(0, 0, createLabel(stringMessages.regatta()));
@@ -116,28 +117,22 @@ public abstract class RegattaLeaderboardDialog extends AbstractLeaderboardDialog
formGrid.setWidget(1, 1, nameTextBox);
formGrid.setWidget(2, 0, createLabel(stringMessages.displayName()));
formGrid.setWidget(2, 1, displayNameTextBox);
-
mainPanel.add(formGrid);
-
- mainPanel.add(new Label(stringMessages.discardRacesFromHowManyStartedRacesOn()));
- HorizontalPanel hp = new HorizontalPanel();
- hp.setSpacing(3);
- for (int i = 0; i < discardThresholdBoxes.length; i++) {
- hp.add(new Label("" + (i + 1) + "."));
- hp.add(discardThresholdBoxes[i]);
+ mainPanel.add(regattaDefinesDiscardsLabel);
+ if (discardThresholdBoxes != null) {
+ mainPanel.add(discardThresholdBoxes.getWidget());
+ regattaDefinesDiscardsLabel.setVisible(false);
}
- alignAllPanelWidgetsVertically(hp, HasVerticalAlignment.ALIGN_MIDDLE);
- mainPanel.add(hp);
return mainPanel;
}
public RegattaDTO getSelectedRegatta() {
RegattaDTO result = null;
int selIndex = regattaListBox.getSelectedIndex();
- if(selIndex > 0) { // the zero index represents the 'no selection' text
+ if (selIndex > 0) { // the zero index represents the 'no selection' text
String itemText = regattaListBox.getItemText(selIndex);
- for(RegattaDTO regattaDTO: existingRegattas) {
- if(regattaDTO.name.equals(itemText)) {
+ for (RegattaDTO regattaDTO : existingRegattas) {
+ if (regattaDTO.name.equals(itemText)) {
result = regattaDTO;
break;
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardEditDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardEditDialog.java
index febb739b0cd..777d720a0cc 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardEditDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardEditDialog.java
@@ -23,6 +23,9 @@ public class RegattaLeaderboardEditDialog extends RegattaLeaderboardDialog {
regattaListBox = createSortedRegattaListBox(existingRegattas, leaderboardDescriptor.getRegattaName());
regattaListBox.setEnabled(false);
- discardThresholdBoxes = initPrefilledDiscardThresholdBoxes(leaderboardDescriptor.getDiscardThresholds(), this);
+ if (leaderboardDescriptor.getDiscardThresholds() != null) {
+ discardThresholdBoxes = new DiscardThresholdBoxes(this, leaderboardDescriptor.getDiscardThresholds(), stringMessages);
+ } // else, the regatta leaderboard obtains its result discarding rule implicitly from the underlying regatta
+ adjustVisibilityOfResultDiscardingRuleComponent();
}
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaStructureManagementPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaStructureManagementPanel.java
index aed0e230fe2..c220309a350 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaStructureManagementPanel.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaStructureManagementPanel.java
@@ -18,7 +18,6 @@ import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sailing.domain.common.Color;
import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.common.dto.FleetDTO;
-import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.gwt.ui.client.DataEntryDialog.DialogCallback;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
@@ -118,15 +117,16 @@ public class RegattaStructureManagementPanel extends SimplePanel implements Rega
}
private void createNewRegatta(final RegattaDTO newRegatta) {
- LinkedHashMap>, Boolean>> seriesStructure =
- new LinkedHashMap>, Boolean>>();
+ LinkedHashMap>, Boolean, int[]>> seriesStructure =
+ new LinkedHashMap>,Boolean,int[]>>();
for (SeriesDTO seriesDTO : newRegatta.series) {
List> fleets = new ArrayList>();
for(FleetDTO fleetDTO : seriesDTO.getFleets()) {
Triple fleetTriple = new Triple(fleetDTO.name, fleetDTO.getOrderNo(), fleetDTO.getColor());
fleets.add(fleetTriple);
}
- Pair>, Boolean> seriesPair = new Pair>, Boolean>(fleets, seriesDTO.isMedal());
+ Triple>, Boolean, int[]> seriesPair = new Triple>, Boolean, int[]>(
+ fleets, seriesDTO.isMedal(), seriesDTO.getDiscardThresholds());
seriesStructure.put(seriesDTO.name, seriesPair);
}
sailingService.createRegatta(newRegatta.name, newRegatta.boatClass==null?null:newRegatta.boatClass.name, seriesStructure, true,
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsCreateDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsCreateDialog.java
index ab3a553843d..e040ca2c8c9 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsCreateDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsCreateDialog.java
@@ -106,7 +106,7 @@ public class RegattaWithSeriesAndFleetsCreateDialog extends RegattaWithSeriesAnd
protected void setupAdditionalWidgetsOnPanel(final VerticalPanel panel) {
panel.add(createHeadlineLabel(stringMessages.series()));
panel.add(seriesGrid);
- Button addSeriesButton = new Button("Add series");
+ Button addSeriesButton = new Button(stringMessages.addSeries());
addSeriesButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsEditDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsEditDialog.java
index f9d51abb9a6..476c49a0440 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsEditDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaWithSeriesAndFleetsEditDialog.java
@@ -17,7 +17,6 @@ public class RegattaWithSeriesAndFleetsEditDialog extends RegattaWithSeriesAndFl
nameEntryField.setEnabled(false);
boatClassEntryField.setEnabled(false);
scoringSchemeListBox.setEnabled(false);
-
sailingEventsListBox.setEnabled(true);
courseAreaListBox.setEnabled(true);
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesDescriptor.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesDescriptor.java
new file mode 100755
index 00000000000..d587eadaf09
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesDescriptor.java
@@ -0,0 +1,43 @@
+package com.sap.sailing.gwt.ui.adminconsole;
+
+import java.util.List;
+
+import com.sap.sailing.domain.common.dto.RaceColumnDTO;
+import com.sap.sailing.gwt.ui.shared.SeriesDTO;
+
+/**
+ * Used by {@link SeriesEditDialog} to capture the result of the user's configuration changes,
+ * including the race columns that the series shall define, the medal status and the discarding rules, if any.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class SeriesDescriptor {
+ private final SeriesDTO series;
+ private final List races;
+ private final boolean isMedal;
+ private final int[] resultDiscardingThresholds;
+
+ public SeriesDescriptor(SeriesDTO series, List races, boolean isMedal, int[] resultDiscardingThresholds) {
+ this.series = series;
+ this.races = races;
+ this.isMedal = isMedal;
+ this.resultDiscardingThresholds = resultDiscardingThresholds;
+ }
+
+ public SeriesDTO getSeries() {
+ return series;
+ }
+
+ public List getRaces() {
+ return races;
+ }
+
+ public boolean isMedal() {
+ return isMedal;
+ }
+
+ public int[] getResultDiscardingThresholds() {
+ return resultDiscardingThresholds;
+ }
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceColumnInRegattaSeriesDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesEditDialog.java
similarity index 75%
rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceColumnInRegattaSeriesDialog.java
rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesEditDialog.java
index e7ab75edb60..1421e728d56 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceColumnInRegattaSeriesDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesEditDialog.java
@@ -7,8 +7,11 @@ import java.util.Set;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
@@ -17,15 +20,16 @@ import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
-import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.gwt.ui.client.DataEntryDialog;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
-public class RaceColumnInRegattaSeriesDialog extends DataEntryDialog>> {
+public class SeriesEditDialog extends DataEntryDialog {
private final ListBox addRacesListBox;
private Button addRacesBtn;
+ private CheckBox isMedalCheckbox;
+ private CheckBox useSeriesResultDiscardingThresholdsCheckbox;
private final List raceNameEntryFields;
private final List