diff --git a/java/com.sap.sailing.feature/feature.xml b/java/com.sap.sailing.feature/feature.xml
index 6eadece9fd1..0b0521fc57e 100755
--- a/java/com.sap.sailing.feature/feature.xml
+++ b/java/com.sap.sailing.feature/feature.xml
@@ -1,377 +1,384 @@
-
-
-
-
+
+
+
+
The SAP Sailing Server.
Provides connectivity to a TracTrac live GPS feed as well as a live feed from an Expedition system.
-Computes leaderboard information for sailing races and offers RESTful APIs to all of this.
-
-
-
- [Enter Copyright Description here.]
-
-
-
- [Enter License Description here.]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+Computes leaderboard information for sailing races and offers RESTful APIs to all of this.
+
+
+
+ [Enter Copyright Description here.]
+
+
+
+ [Enter License Description here.]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractDiscardThresholdBoxes.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractDiscardThresholdBoxes.java
new file mode 100755
index 00000000000..5b1ba493dc1
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractDiscardThresholdBoxes.java
@@ -0,0 +1,118 @@
+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.StringMessages;
+import com.sap.sse.gwt.client.dialog.DataEntryDialog;
+
+/**
+ * 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.
+ *
+ * This class is abstract and can be instantiated by using an anonymous inner class of the enclosing dialog parent class
+ * which needs to be a subclass of {@link DataEntryDialog}. Alternatively, clients can use the concrete subclass
+ * {@link DiscardThresholdBoxes} and can provide the data entry dialog parent object explicitly.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public abstract class AbstractDiscardThresholdBoxes {
+ private static final int MAX_NUMBER_OF_DISCARDED_RESULTS = 4;
+
+ private final LongBox[] discardThresholdBoxes;
+
+ /**
+ * The widget used to represent the UI
+ */
+ private final Widget widget;
+
+ public AbstractDiscardThresholdBoxes(StringMessages stringMessages) {
+ this(/* values to show */ new int[0], stringMessages);
+ }
+
+ public AbstractDiscardThresholdBoxes(int[] initialDiscardThresholds, StringMessages stringMessages) {
+ discardThresholdBoxes = new LongBox[MAX_NUMBER_OF_DISCARDED_RESULTS];
+ for (int i = 0; i < discardThresholdBoxes.length; i++) {
+ if (initialDiscardThresholds != null && i < initialDiscardThresholds.length) {
+ discardThresholdBoxes[i] = getParent().createLongBox(initialDiscardThresholds[i], 2);
+ } else {
+ discardThresholdBoxes[i] = getParent().createLongBoxWithOptionalValue(null, 2);
+ }
+ discardThresholdBoxes[i].setVisibleLength(2);
+ }
+ widget = createDiscardThresholdBoxesPanel(stringMessages);
+ }
+
+ protected abstract DataEntryDialog> getParent();
+
+ /**
+ * @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]);
+ }
+ getParent().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/SeriesWithFleetsCreateDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsCreateDialog.java
index e6ffba52a23..eced4001981 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
@@ -30,13 +30,13 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog {
private StringMessages stringMessages;
private SeriesDTO series;
- protected TextBox nameEntryField;
+ protected final TextBox nameEntryField;
protected CheckBox isMedalSeriesCheckbox;
protected CheckBox startsWithZeroScoreCheckbox;
protected CheckBox hasSplitFleetContiguousScoringCheckbox;
protected CheckBox firstColumnIsNonDiscardableCarryForwardCheckbox;
protected CheckBox useSeriesResultDiscardingThresholdsCheckbox;
- protected DiscardThresholdBoxes discardThresholdBoxes;
+ protected final DiscardThresholdBoxes discardThresholdBoxes;
protected ListEditorComposite fleetListComposite;
protected static class SeriesParameterValidator implements Validator {
@@ -99,12 +99,19 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog {
public SeriesWithFleetsCreateDialog(Collection existingSeries, StringMessages stringMessages,
DialogCallback callback) {
+ this(existingSeries, stringMessages, /* discard thresholds */ null, callback);
+ }
+
+ protected SeriesWithFleetsCreateDialog(Collection existingSeries, StringMessages stringMessages,
+ int[] discardThresholds, DialogCallback callback) {
super(stringMessages.series(), null, stringMessages.ok(), stringMessages.cancel(),
new SeriesParameterValidator(stringMessages, existingSeries), callback);
this.stringMessages = stringMessages;
this.series = new SeriesDTO();
-
- setNameEntryField();
+ this.discardThresholdBoxes = discardThresholds == null ? new DiscardThresholdBoxes(this, stringMessages) : new DiscardThresholdBoxes(this, discardThresholds, stringMessages);
+ nameEntryField = createTextBox(null);
+ nameEntryField.ensureDebugId("NameTextBox");
+ nameEntryField.setVisibleLength(40);
isMedalSeriesCheckbox = createCheckbox(stringMessages.medalSeries());
isMedalSeriesCheckbox.ensureDebugId("MedalSeriesCheckbox");
@@ -123,11 +130,9 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog {
useSeriesResultDiscardingThresholdsCheckbox.addValueChangeHandler(new ValueChangeHandler() {
@Override
public void onValueChange(ValueChangeEvent event) {
- discardThresholdBoxes.getWidget().setVisible(event.getValue());
+ SeriesWithFleetsCreateDialog.this.discardThresholdBoxes.getWidget().setVisible(event.getValue());
}
});
-
- discardThresholdBoxes = new DiscardThresholdBoxes(this, stringMessages);
Widget widget = discardThresholdBoxes.getWidget();
widget.ensureDebugId("DiscardThresholdBoxes");
widget.setVisible(false);
@@ -135,8 +140,9 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog {
initializeFleetListComposite(stringMessages);
}
- protected void initializeFleetListComposite(StringMessages stringMessages) {
- fleetListComposite = new FleetListEditorComposite(Arrays.asList(new FleetDTO(LeaderboardNameConstants.DEFAULT_FLEET_NAME, 0, null)), stringMessages, resources.removeIcon());
+ protected void initializeFleetListComposite(StringMessages stringMessages) {
+ fleetListComposite = new FleetListEditorComposite(Arrays.asList(new FleetDTO(
+ LeaderboardNameConstants.DEFAULT_FLEET_NAME, 0, null)), stringMessages, resources.removeIcon());
fleetListComposite.ensureDebugId("FleetListEditorComposite");
fleetListComposite.addValueChangeHandler(new ValueChangeHandler>() {
@Override
@@ -144,13 +150,7 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog {
validate();
}
});
- }
-
- protected void setNameEntryField() {
- nameEntryField = createTextBox(null);
- nameEntryField.ensureDebugId("NameTextBox");
- nameEntryField.setVisibleLength(40);
- }
+ }
@Override
protected SeriesDTO getResult() {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsDefaultCreateDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsDefaultCreateDialog.java
index d40b4b663c1..952e59907d2 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsDefaultCreateDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SeriesWithFleetsDefaultCreateDialog.java
@@ -16,14 +16,13 @@ import com.sap.sailing.gwt.ui.shared.SeriesDTO;
public class SeriesWithFleetsDefaultCreateDialog extends SeriesWithFleetsCreateDialog {
public SeriesWithFleetsDefaultCreateDialog(SeriesDTO defaultSeries, StringMessages stringMessages,
com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback callback) {
- super(Collections. emptyList(), stringMessages, callback);
+ super(Collections. emptyList(), stringMessages, defaultSeries.getDiscardThresholds(), callback);
nameEntryField.setText(defaultSeries.getName());// Otherwise an errorMessage will pop up
isMedalSeriesCheckbox.setValue(defaultSeries.isFirstColumnIsNonDiscardableCarryForward());
startsWithZeroScoreCheckbox.setValue(defaultSeries.isStartsWithZeroScore());
hasSplitFleetContiguousScoringCheckbox.setValue(defaultSeries.hasSplitFleetContiguousScoring());
firstColumnIsNonDiscardableCarryForwardCheckbox.setValue(defaultSeries.isFirstColumnIsNonDiscardableCarryForward());
useSeriesResultDiscardingThresholdsCheckbox.setValue(defaultSeries.definesSeriesDiscardThresholds());
- discardThresholdBoxes.setDiscardThresholds(defaultSeries.getDiscardThresholds());
fleetListComposite.setValue(defaultSeries.getFleets());
}
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy).launch b/java/com.sap.sailing.server/SailingServer (No Proxy).launch
index df2c7ad2ae9..abdcdda2e74 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy).launch
@@ -33,5 +33,5 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
index 2b4710353f6..4c8b3a151ed 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
@@ -32,5 +32,5 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
index 707fdbef652..ec1be52c177 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
@@ -26,6 +26,6 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
index 45e672bdec0..70c1cc715ad 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
@@ -27,6 +27,6 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
index a94d5c2f4ca..301265e12cc 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
@@ -26,5 +26,5 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
index cdd2087e255..65360e587c1 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
@@ -32,5 +32,5 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy).launch b/java/com.sap.sailing.server/SailingServer (Proxy).launch
index df399691dd1..9c7d360e12e 100644
--- a/java/com.sap.sailing.server/SailingServer (Proxy).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy).launch
@@ -33,6 +33,6 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch
index ec7115e5c53..a0182edfd34 100644
--- a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch
@@ -26,6 +26,6 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch
index 8fb5c32465b..d19d0d6849b 100644
--- a/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch
@@ -26,5 +26,5 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch b/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch
index d2b2f499cd2..31a5acda5d5 100644
--- a/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch
@@ -25,5 +25,5 @@
-
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch
index 3011cd9e205..9ac223baaab 100644
--- a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch
@@ -26,6 +26,6 @@
-
+