From d0141154056659823a2017073b1e706d59ec1fd2 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 6 Jun 2013 02:03:27 +0200 Subject: [PATCH] supporting regatta / series creation with series-specific discarding rules --- .../RegattaStructureManagementPanel.java | 8 +-- .../SeriesWithFleetsCreateDialog.java | 61 ++++++++++++------- .../sailing/gwt/ui/client/SailingService.java | 2 +- .../gwt/ui/client/SailingServiceAsync.java | 2 +- .../gwt/ui/server/SailingServiceImpl.java | 2 +- .../sap/sailing/gwt/ui/shared/SeriesDTO.java | 4 ++ .../adminconsole/TestLeaderboardCreation.java | 2 - .../pages/LeaderboardConfigurationPanel.java | 1 - .../server/impl/RacingEventServiceImpl.java | 9 ++- .../AddSpecificRegatta.java | 13 ++-- 10 files changed, 63 insertions(+), 41 deletions(-) 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/SeriesWithFleetsCreateDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsCreateDialog.java index 24101d12e8b..1beabe6dc53 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsCreateDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsCreateDialog.java @@ -9,6 +9,8 @@ import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Grid; @@ -26,11 +28,13 @@ import com.sap.sailing.gwt.ui.shared.SeriesDTO; public class SeriesWithFleetsCreateDialog extends DataEntryDialog { - private StringMessages stringConstants; + private StringMessages stringMessages; private SeriesDTO series; private TextBox nameEntryField; private CheckBox isMedalSeriesCheckbox; + private CheckBox useSeriesResultDiscardingThresholdsCheckbox; + private DiscardThresholdBoxes discardThresholdBoxes; private List fleetNameEntryFields; private List fleetColorEntryFields; @@ -39,12 +43,11 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog { private Grid fleetsGrid; protected static class SeriesParameterValidator implements Validator { - - private StringMessages stringConstants; + private StringMessages stringMessages; private ArrayList existingSeries; public SeriesParameterValidator(StringMessages stringConstants, Collection existingSeries) { - this.stringConstants = stringConstants; + this.stringMessages = stringConstants; this.existingSeries = new ArrayList(existingSeries); } @@ -60,9 +63,9 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog { } } if (!nameNotEmpty) { - errorMessage = stringConstants.pleaseEnterAName(); + errorMessage = stringMessages.pleaseEnterAName(); } else if (!unique) { - errorMessage = stringConstants.seriesWithThisNameAlreadyExists(); + errorMessage = stringMessages.seriesWithThisNameAlreadyExists(); } if (errorMessage == null) { List fleetsToValidate = seriesToValidate.getFleets(); @@ -86,32 +89,41 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog { index2++; } if (!fleetNameNotEmpty) { - errorMessage = stringConstants.fleet() + " " + (index + 1) + ": " + stringConstants.pleaseEnterAName(); + errorMessage = stringMessages.fleet() + " " + (index + 1) + ": " + stringMessages.pleaseEnterAName(); } else if (!fleetUnique) { - errorMessage = stringConstants.fleet() + " " + (index2 + 1) + ": " + stringConstants.fleetWithThisNameAlreadyExists(); + errorMessage = stringMessages.fleet() + " " + (index2 + 1) + ": " + stringMessages.fleetWithThisNameAlreadyExists(); + } else { + errorMessage = DiscardThresholdBoxes.getErrorMessage(seriesToValidate.getDiscardThresholds(), stringMessages); } } return errorMessage; } } - public SeriesWithFleetsCreateDialog(Collection existingSeries, StringMessages stringConstants, + public SeriesWithFleetsCreateDialog(Collection existingSeries, StringMessages stringMessages, DialogCallback callback) { - super(stringConstants.series(), null, stringConstants.ok(), stringConstants.cancel(), - new SeriesParameterValidator(stringConstants, existingSeries), callback); - this.stringConstants = stringConstants; + super(stringMessages.series(), null, stringMessages.ok(), stringMessages.cancel(), + new SeriesParameterValidator(stringMessages, existingSeries), callback); + this.stringMessages = stringMessages; this.series = new SeriesDTO(); nameEntryField = createTextBox(null); nameEntryField.setVisibleLength(40); - isMedalSeriesCheckbox = createCheckbox(stringConstants.medalSeries()); + isMedalSeriesCheckbox = createCheckbox(stringMessages.medalSeries()); + useSeriesResultDiscardingThresholdsCheckbox = createCheckbox(stringMessages.seriesDefinesResultDiscardingRule()); + useSeriesResultDiscardingThresholdsCheckbox.addValueChangeHandler(new ValueChangeHandler() { + @Override + public void onValueChange(ValueChangeEvent event) { + discardThresholdBoxes.getWidget().setVisible(event.getValue()); + } + }); + discardThresholdBoxes = new DiscardThresholdBoxes(this, stringMessages); + discardThresholdBoxes.getWidget().setVisible(false); fleetNameEntryFields = new ArrayList(); fleetColorEntryFields = new ArrayList(); fleetOrderNoEntryFields = new ArrayList(); fleetsGrid = new Grid(0, 0); // create at least one fleet addFleetWidget("Default", 0, null); - - // TODO bug 1414 add checkbox for enabling series-specific result discarding and, if checked, show the discard threshold boxes to be shared with leaderboard create/edit dialogs } private Widget createFleetNameWidget(String defaultName) { @@ -145,7 +157,7 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog { validate(); } }); - listBox.addItem(stringConstants.noColor()); + listBox.addItem(stringMessages.noColor()); for(FleetColors value: FleetColors.values()) { listBox.addItem(value.name()); } @@ -180,6 +192,7 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog { fleets.add(fleetDTO); } series.setFleets(fleets); + series.setDiscardThresholds(useSeriesResultDiscardingThresholdsCheckbox.getValue() ? discardThresholdBoxes.getDiscardThresholds() : null); return series; } @@ -206,14 +219,16 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog { if (additionalWidget != null) { panel.add(additionalWidget); } - Grid formGrid = new Grid(2, 2); + Grid formGrid = new Grid(4, 2); panel.add(formGrid); - formGrid.setWidget(0, 0, new Label(stringConstants.name() + ":")); + formGrid.setWidget(0, 0, new Label(stringMessages.name() + ":")); formGrid.setWidget(0, 1, nameEntryField); formGrid.setWidget(1, 1, isMedalSeriesCheckbox); - panel.add(createHeadlineLabel(stringConstants.fleets())); + formGrid.setWidget(2, 1, useSeriesResultDiscardingThresholdsCheckbox); + formGrid.setWidget(3, 1, discardThresholdBoxes.getWidget()); + panel.add(createHeadlineLabel(stringMessages.fleets())); panel.add(fleetsGrid); - Button addFleetButton = new Button(stringConstants.addFleet()); + Button addFleetButton = new Button(stringMessages.addFleet()); addFleetButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { @@ -238,9 +253,9 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog { int fleetCount = fleetNameEntryFields.size(); fleetsGrid = new Grid(fleetCount + 1, 3); fleetsGrid.setCellSpacing(4); - fleetsGrid.setHTML(0, 0, stringConstants.color()); - fleetsGrid.setHTML(0, 1, stringConstants.name()); - fleetsGrid.setHTML(0, 2, stringConstants.rank()); + fleetsGrid.setHTML(0, 0, stringMessages.color()); + fleetsGrid.setHTML(0, 1, stringMessages.name()); + fleetsGrid.setHTML(0, 2, stringMessages.rank()); for(int i = 0; i < fleetCount; i++) { fleetsGrid.setWidget(i+1, 0, fleetColorEntryFields.get(i)); fleetsGrid.setWidget(i+1, 1, fleetNameEntryFields.get(i)); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 00613c3c46f..791f42d03c4 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -143,7 +143,7 @@ public interface SailingService extends RemoteService { void moveLeaderboardColumnDown(String leaderboardName, String columnName); RegattaDTO createRegatta(String regattaName, String boatClassName, - LinkedHashMap>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, + LinkedHashMap>, Boolean, int[]>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent, ScoringSchemeType scoringSchemeType, String defaultCourseAreaId); void removeRegatta(RegattaIdentifier regattaIdentifier); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index 38bbfad8d9c..2bf6033f390 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -364,7 +364,7 @@ public interface SailingServiceAsync { AsyncCallback callback); void createRegatta(String regattaName, String boatClassName, - LinkedHashMap>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, + LinkedHashMap>, Boolean, int[]>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent, ScoringSchemeType scoringSchemeType, String defaultCourseAreaId, AsyncCallback callback); void addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, List columnNames, diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 7b545f9cb9f..d304c13cbf2 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -2525,7 +2525,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public RegattaDTO createRegatta(String regattaName, String boatClassName, - LinkedHashMap>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, + LinkedHashMap>, Boolean, int[]>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent, ScoringSchemeType scoringSchemeType, String defaultCourseAreaId) { UUID courseAreaUuid = convertIdentifierStringToUuid(defaultCourseAreaId); Regatta regatta = getService().apply( diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SeriesDTO.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SeriesDTO.java index 4767e06431b..bddc1a437c5 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SeriesDTO.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/SeriesDTO.java @@ -50,4 +50,8 @@ public class SeriesDTO extends NamedDTO { public int[] getDiscardThresholds() { return discardThresholds; } + + public void setDiscardThresholds(int[] discardThresholds) { + this.discardThresholds = discardThresholds; + } } diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestLeaderboardCreation.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestLeaderboardCreation.java index 852f290f3aa..190c3970354 100755 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestLeaderboardCreation.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestLeaderboardCreation.java @@ -3,11 +3,9 @@ package com.sap.sailing.selenium.test.adminconsole; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import org.junit.Before; import org.junit.Test; import com.sap.sailing.selenium.test.AbstractSeleniumTest; -import com.sap.sailing.selenium.test.DatabaseHelper; import com.sap.sailing.selenium.test.adminconsole.pages.AdminConsolePage; import com.sap.sailing.selenium.test.adminconsole.pages.FlexibleLeaderboardCreationDialog; import com.sap.sailing.selenium.test.adminconsole.pages.LeaderboardConfigurationPanel; diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/pages/LeaderboardConfigurationPanel.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/pages/LeaderboardConfigurationPanel.java index a3588736b17..0e912ff88a3 100755 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/pages/LeaderboardConfigurationPanel.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/pages/LeaderboardConfigurationPanel.java @@ -1,7 +1,6 @@ package com.sap.sailing.selenium.test.adminconsole.pages; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import org.openqa.selenium.By; diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java index 24265ff430e..39ce536b12b 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java @@ -824,15 +824,18 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen } } - private Map>, Boolean>> getSeriesWithoutRaceColumnsConstructionParametersAsMap(Regatta regatta) { - Map>, Boolean>> result = new HashMap>, Boolean>>(); + private Map>, Boolean, int[]>> getSeriesWithoutRaceColumnsConstructionParametersAsMap( + Regatta regatta) { + Map>, Boolean, int[]>> result = + new HashMap>, Boolean, int[]>>(); for (Series s : regatta.getSeries()) { assert Util.isEmpty(s.getRaceColumns()); List> fleetNamesAndOrdering = new ArrayList>(); for (Fleet f : s.getFleets()) { fleetNamesAndOrdering.add(new Triple(f.getName(), f.getOrdering(), f.getColor())); } - result.put(s.getName(), new Pair>, Boolean>(fleetNamesAndOrdering, s.isMedal())); + result.put(s.getName(), new Triple>, Boolean, int[]>(fleetNamesAndOrdering, s.isMedal(), + s.getResultDiscardingRule() == null ? null : s.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces())); } return result; } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddSpecificRegatta.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddSpecificRegatta.java index 64fce2c8dad..a081cab96d5 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddSpecificRegatta.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/operationaltransformation/AddSpecificRegatta.java @@ -12,25 +12,25 @@ import com.sap.sailing.domain.base.Series; import com.sap.sailing.domain.base.impl.FleetImpl; import com.sap.sailing.domain.base.impl.SeriesImpl; import com.sap.sailing.domain.common.Color; -import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; import com.sap.sailing.domain.leaderboard.ScoringScheme; +import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl; import com.sap.sailing.domain.tracking.TrackedRegattaRegistry; import com.sap.sailing.server.RacingEventService; import com.sap.sailing.server.RacingEventServiceOperation; public class AddSpecificRegatta extends AbstractAddRegattaOperation { private static final long serialVersionUID = -8018855620167669352L; - private final Map>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal; + private final Map>, Boolean, int[]>> seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndDiscardingThresholds; private final boolean persistent; private final ScoringScheme scoringScheme; private final Serializable defaultCourseAreaId; public AddSpecificRegatta(String regattaName, String boatClassName, Serializable id, - Map>, Boolean>> seriesNamesWithFleetNamesAndFleetOrdering, + Map>, Boolean, int[]>> seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndDiscardingThresholds, boolean persistent, ScoringScheme scoringScheme, Serializable defaultCourseAreaId) { super(regattaName, boatClassName, id); - this.seriesNamesWithFleetNamesAndFleetOrderingAndMedal = seriesNamesWithFleetNamesAndFleetOrdering; + this.seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndDiscardingThresholds = seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndDiscardingThresholds; this.persistent = persistent; this.scoringScheme = scoringScheme; this.defaultCourseAreaId = defaultCourseAreaId; @@ -44,10 +44,13 @@ public class AddSpecificRegatta extends AbstractAddRegattaOperation { private Iterable createSeries(TrackedRegattaRegistry trackedRegattaRegistry) { List result = new ArrayList(); - for (Map.Entry>, Boolean>> e : seriesNamesWithFleetNamesAndFleetOrderingAndMedal.entrySet()) { + for (Map.Entry>, Boolean, int[]>> e : seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndDiscardingThresholds.entrySet()) { final List emptyRaceColumnNamesList = Collections.emptyList(); Series s = new SeriesImpl(e.getKey(), /* isMedal */e.getValue().getB(), createFleets(e.getValue().getA()), emptyRaceColumnNamesList, trackedRegattaRegistry); + if (e.getValue().getC() != null) { + s.setResultDiscardingRule(new ThresholdBasedResultDiscardingRuleImpl(e.getValue().getC())); + } result.add(s); } return result;