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 @@ - +