From 6aae14f76fb8b3ce51afef051d2804ebf832e350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Thu, 6 Jun 2019 15:24:08 +0200 Subject: [PATCH 01/17] Implemented first prototype of resultsPresenter orientation changer in DataMining --- .../ui/datamining/DataMiningEntryPoint.java | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java index 4ef1f0133b2..79312d7f0fa 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java @@ -6,6 +6,8 @@ import java.util.logging.Logger; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.http.client.UrlBuilder; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONObject; @@ -13,6 +15,7 @@ import com.google.gwt.json.client.JSONParser; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.ServiceDefTarget; +import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.RootLayoutPanel; import com.google.gwt.user.client.ui.SplitLayoutPanel; @@ -58,6 +61,12 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { private final DataMiningServiceAsync dataMiningService = GWT.create(DataMiningService.class); private DataMiningSession session; + private QueryDefinitionProviderWithControls queryDefinitionProvider; + private CompositeResultsPresenter resultsPresenter; + + private SplitLayoutPanel queryAndResultSplitPanel; + private boolean queryAndResultAreVertical = true; + @Override protected void doOnModuleLoad() { Highcharts.ensureInjectedWithMore(); @@ -78,7 +87,6 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { authorizedContentDecorator.setPermissionToCheck(serverInfo, ServerActions.DATA_MINING); authorizedContentDecorator.setContentWidgetFactory(new WidgetFactory() { - private QueryDefinitionProviderWithControls queryDefinitionProvider; private SimpleQueryRunner queryRunner; private final DataMiningSettingsInfoManager settingsManager = new DataMiningSettingsInfoManagerImpl( getStringMessages()); @@ -86,7 +94,7 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { @Override public Widget get() { DataMiningSettingsControl settingsControl = new AnchorDataMiningSettingsControl(null, null); - CompositeResultsPresenter resultsPresenter = new TabbedSailingResultsPresenter(/* parent */ null, + resultsPresenter = new TabbedSailingResultsPresenter(/* parent */ null, /* context */ null, /* drillDownCallback */ groupKey -> { queryDefinitionProvider.drillDown(groupKey, () -> { queryRunner.run(queryDefinitionProvider.getQueryDefinition()); @@ -111,6 +119,15 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { queryDefinitionProvider, dataMiningService, queryRunner); queryDefinitionProvider.addControl(new StoredDataMiningQueryPanel(dataProvider)); } + + Button orientationButton = new Button("Orientation"); //TODO Use icon or i18n string + orientationButton.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + setQueryAndResultOrientation(); + } + }); + queryDefinitionProvider.addControl(orientationButton); /* * Running queries automatically when they've been changed is currently unnecessary, if not even * counterproductive. This removes the query runner settings to prevent that the user can enable the @@ -118,9 +135,8 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { */ // settingsControl.addSettingsComponent(queryRunner); - SplitLayoutPanel splitPanel = new SplitLayoutPanel(10); - splitPanel.addSouth(resultsPresenter.getEntryWidget(), 350); - splitPanel.add(queryDefinitionProvider.getEntryWidget()); + queryAndResultSplitPanel = new SplitLayoutPanel(10); + addDefinitionProviderAndResultPresenter(); if (queryIdentifier != null) { if (Storage.isLocalStorageSupported()) { @@ -153,7 +169,7 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { NotificationType.ERROR); } } - return splitPanel; + return queryAndResultSplitPanel; } }); @@ -165,6 +181,39 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { rootPanel.add(panel); } + /** + * Toggles the position of the {@link #resultsPresenter} from south to east and vice versa. + */ + public void setQueryAndResultOrientation() { + setQueryAndResultOrientation(!queryAndResultAreVertical); + } + /** + * Sets the position of the {@link #resultsPresenter}. + * @param vertical {@code boolean} {@code true} places it in the south position + * and {@code false} in the east position. + */ + public void setQueryAndResultOrientation(boolean vertical) { + if (vertical != queryAndResultAreVertical) { + queryAndResultAreVertical = vertical; + + queryAndResultSplitPanel.remove(resultsPresenter.getEntryWidget()); + // You can't add panels as long as there is a center panel so temporarily remove it + queryAndResultSplitPanel.remove(queryDefinitionProvider.getEntryWidget()); + + // Add the center panel back once the changes are made + addDefinitionProviderAndResultPresenter(); + } + } + + private void addDefinitionProviderAndResultPresenter() { + if (queryAndResultAreVertical) { + queryAndResultSplitPanel.addSouth(resultsPresenter.getEntryWidget(), 350); + } else { + queryAndResultSplitPanel.addEast(resultsPresenter.getEntryWidget(), 400); + } + queryAndResultSplitPanel.add(queryDefinitionProvider.getEntryWidget()); + } + private void removeUrlParameter() { try { UrlBuilder builder = Window.Location.createUrlBuilder().setHost(Window.Location.getHost()) From df791116c8da9c850dde63a8d49cf7b392f7892c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Thu, 13 Jun 2019 14:37:25 +0200 Subject: [PATCH 02/17] Adjusted suggestBox width and resultPresenter size in DataMining --- .../sailing/gwt/ui/datamining/DataMiningEntryPoint.java | 7 +++++-- .../selection/QueryDefinitionProviderWithControls.java | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java index 79312d7f0fa..db098b10fac 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java @@ -58,6 +58,9 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { public static final ComponentResources resources = GWT.create(ComponentResources.class); private static final Logger LOG = Logger.getLogger(DataMiningEntryPoint.class.getName()); + private static final int resultsPresenterSouthInitialHeight = 350; + private static final int resultsPresenterEastInitialWidth = 700; + private final DataMiningServiceAsync dataMiningService = GWT.create(DataMiningService.class); private DataMiningSession session; @@ -207,9 +210,9 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { private void addDefinitionProviderAndResultPresenter() { if (queryAndResultAreVertical) { - queryAndResultSplitPanel.addSouth(resultsPresenter.getEntryWidget(), 350); + queryAndResultSplitPanel.addSouth(resultsPresenter.getEntryWidget(), resultsPresenterSouthInitialHeight); } else { - queryAndResultSplitPanel.addEast(resultsPresenter.getEntryWidget(), 400); + queryAndResultSplitPanel.addEast(resultsPresenter.getEntryWidget(), resultsPresenterEastInitialWidth); } queryAndResultSplitPanel.add(queryDefinitionProvider.getEntryWidget()); } diff --git a/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java b/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java index f6cf540a18c..b208dcf86ba 100644 --- a/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java +++ b/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java @@ -72,7 +72,7 @@ public class QueryDefinitionProviderWithControls extends AbstractQueryDefinition private static final double HeaderPanelHeight = 41; private static final double InitialQueryDefinitionViewerWidth = 600; - private static final double InitialStatisticProviderWidth = 800; + private static final double InitialStatisticProviderWidth = 500; private static final double FooterPanelHeight = 60; private static final int SplitterSize = 10; From 6404541913727f7279e53e7f462b766ab4d5edc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Thu, 13 Jun 2019 15:18:32 +0200 Subject: [PATCH 03/17] ResultsPresenter will remember previous size when changing orientation --- .../ui/datamining/DataMiningEntryPoint.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java index db098b10fac..aa44185c810 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java @@ -58,14 +58,13 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { public static final ComponentResources resources = GWT.create(ComponentResources.class); private static final Logger LOG = Logger.getLogger(DataMiningEntryPoint.class.getName()); - private static final int resultsPresenterSouthInitialHeight = 350; - private static final int resultsPresenterEastInitialWidth = 700; - private final DataMiningServiceAsync dataMiningService = GWT.create(DataMiningService.class); private DataMiningSession session; private QueryDefinitionProviderWithControls queryDefinitionProvider; private CompositeResultsPresenter resultsPresenter; + private Integer resultsPresenterSouthHeight = 350; + private Integer resultsPresenterEastWidth = 750; private SplitLayoutPanel queryAndResultSplitPanel; private boolean queryAndResultAreVertical = true; @@ -197,6 +196,16 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { */ public void setQueryAndResultOrientation(boolean vertical) { if (vertical != queryAndResultAreVertical) { + // Store current size for the next orientation change + Double size = queryAndResultSplitPanel.getWidgetSize(resultsPresenter.getEntryWidget()); + if (size != null) { + if (queryAndResultAreVertical) { + resultsPresenterSouthHeight = size.intValue(); + } else { + resultsPresenterEastWidth = size.intValue(); + } + } + queryAndResultAreVertical = vertical; queryAndResultSplitPanel.remove(resultsPresenter.getEntryWidget()); @@ -210,9 +219,9 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { private void addDefinitionProviderAndResultPresenter() { if (queryAndResultAreVertical) { - queryAndResultSplitPanel.addSouth(resultsPresenter.getEntryWidget(), resultsPresenterSouthInitialHeight); + queryAndResultSplitPanel.addSouth(resultsPresenter.getEntryWidget(), resultsPresenterSouthHeight); } else { - queryAndResultSplitPanel.addEast(resultsPresenter.getEntryWidget(), resultsPresenterEastInitialWidth); + queryAndResultSplitPanel.addEast(resultsPresenter.getEntryWidget(), resultsPresenterEastWidth); } queryAndResultSplitPanel.add(queryDefinitionProvider.getEntryWidget()); } From ce45ee67d541ad21ba6b83b6eeb2c1cb846a6c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Thu, 13 Jun 2019 15:43:27 +0200 Subject: [PATCH 04/17] Overlapping the control buttons with the resultPresenter will no longer make the buttons disappear into the next line --- .../selection/QueryDefinitionProviderWithControls.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java b/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java index b208dcf86ba..112f78ed4cb 100644 --- a/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java +++ b/java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java @@ -11,7 +11,9 @@ import java.util.function.Consumer; import com.google.gwt.dom.builder.shared.HtmlBuilderFactory; import com.google.gwt.dom.builder.shared.HtmlUListBuilder; +import com.google.gwt.dom.client.Style.Overflow; import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.dom.client.Style.WhiteSpace; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.i18n.client.LocaleInfo; @@ -108,6 +110,10 @@ public class QueryDefinitionProviderWithControls extends AbstractQueryDefinition // Creating the header panel, that contains the retriever chain provider and the controls controlsPanel = new FlowPanel(); controlsPanel.addStyleName("dataMiningMarginBase"); + // The following 2 lines restrict controlsPanel to using one line + // instead of pushing its content into the next line when there is not enough space. + controlsPanel.getElement().getStyle().setOverflow(Overflow.HIDDEN); + controlsPanel.getElement().getStyle().setWhiteSpace(WhiteSpace.NOWRAP); this.settingsControl = settingsControl; addControl(this.settingsControl.getEntryWidget()); From 9a2f73ff6fb4747b692a75336f867f8bee7db624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Fri, 21 Jun 2019 17:11:42 +0200 Subject: [PATCH 05/17] Added storage support for private tags --- .../ui/raceboard/tagging/TaggingPanel.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java index 8d07383dd79..e64a085f6a1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java @@ -10,6 +10,7 @@ import com.google.gwt.core.shared.GWT; import com.google.gwt.dom.client.BrowserEvents; import com.google.gwt.user.cellview.client.CellList; import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy; +import com.google.gwt.user.client.Random; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; @@ -38,6 +39,7 @@ import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.media.MediaTagConstants; import com.sap.sse.gwt.client.Notification; import com.sap.sse.gwt.client.Notification.NotificationType; +import com.sap.sse.gwt.client.Storage; import com.sap.sse.gwt.client.media.ImageDTO; import com.sap.sse.gwt.client.media.ImageResizingTaskDTO; import com.sap.sse.gwt.client.player.TimeListener; @@ -71,6 +73,10 @@ public class TaggingPanel extends ComponentWithoutSettings CREATE_TAG, EDIT_TAG } + // HTML5 Storage for notifying other instances of tag changes + private static final String LOCAL_STORAGE_UPDATE_KEY = "private-tags-changed"; + private final String id; + // styling private final TagPanelStyle style; @@ -132,6 +138,7 @@ public class TaggingPanel extends ComponentWithoutSettings StrippedLeaderboardDTOWithSecurity leaderboardDTO) { super(parent, context); + this.id = Long.toString(System.currentTimeMillis() * Random.nextInt()); this.stringMessages = stringMessages; this.sailingService = sailingService; this.userService = userService; @@ -162,6 +169,8 @@ public class TaggingPanel extends ComponentWithoutSettings userService.addUserStatusEventHandler(this); raceTimesInfoProvider.addRaceTimesInfoProviderListener(this); + registerStorageEventHandler(); + setCurrentState(State.VIEW); initializePanel(); } @@ -225,6 +234,28 @@ public class TaggingPanel extends ComponentWithoutSettings updateContent(); } + /** + * Registers a storage event handler that reloads the private tags if another instance has updated them. + */ + private void registerStorageEventHandler() { + Storage.addStorageEventHandler(event -> { + if (LOCAL_STORAGE_UPDATE_KEY.equals(event.getKey()) && event.getNewValue() != null + && !event.getNewValue().isEmpty() && !event.getNewValue().equals(id.toString())) { + reloadPrivateTags(); + } + }); + } + + /** + * Notifies other instances that the private tags have changed. + */ + private void firePrivateTagUpdateEvent() { + if (Storage.isSupported()) { + Storage.getLocalStorageIfSupported().setItem(LOCAL_STORAGE_UPDATE_KEY, ""); // Force update + Storage.getLocalStorageIfSupported().setItem(LOCAL_STORAGE_UPDATE_KEY, id); + } + } + /** * Updates parameters required to save/revoke {@link com.sap.sailing.domain.abstractlog.race.RaceLogEvent events} * to/from {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog}. @@ -374,6 +405,7 @@ public class TaggingPanel extends ComponentWithoutSettings // reload private tags if added tag is private if (!visibleForPublic) { reloadPrivateTags(); + firePrivateTagUpdateEvent(); } } else { Notification.notify(stringMessages.tagNotSavedReason(result.getMessage()), @@ -421,6 +453,7 @@ public class TaggingPanel extends ComponentWithoutSettings if (!silent) { Notification.notify(stringMessages.tagRemovedSuccessfully(), NotificationType.SUCCESS); } + firePrivateTagUpdateEvent(); } else { Notification.notify(stringMessages.tagNotRemoved() + " " + result.getMessage(), NotificationType.ERROR); @@ -464,6 +497,7 @@ public class TaggingPanel extends ComponentWithoutSettings // refresh UI. if (!tagToUpdate.isVisibleForPublic() || !visibleForPublic) { reloadPrivateTags(); + firePrivateTagUpdateEvent(); } else { updateContent(); } From d3e8f5a8f3cfe80bc001d56b70167581cb3d53fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Fri, 21 Jun 2019 17:31:08 +0200 Subject: [PATCH 06/17] Fixed double update when notifying about a private tag change --- .../gwt/ui/raceboard/tagging/TaggingPanel.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java index e64a085f6a1..49ca4e32f26 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/tagging/TaggingPanel.java @@ -75,7 +75,6 @@ public class TaggingPanel extends ComponentWithoutSettings // HTML5 Storage for notifying other instances of tag changes private static final String LOCAL_STORAGE_UPDATE_KEY = "private-tags-changed"; - private final String id; // styling private final TagPanelStyle style; @@ -115,6 +114,9 @@ public class TaggingPanel extends ComponentWithoutSettings protected final TimePoint timePointToHighlight; protected final String tagToHighlight; + // ID for inter-instance communication + private String id; + /** * This boolean prevents the timer from jumping when other users create or delete tags. The timer change event is * called by the selection change event and the other way around. When:
@@ -138,7 +140,6 @@ public class TaggingPanel extends ComponentWithoutSettings StrippedLeaderboardDTOWithSecurity leaderboardDTO) { super(parent, context); - this.id = Long.toString(System.currentTimeMillis() * Random.nextInt()); this.stringMessages = stringMessages; this.sailingService = sailingService; this.userService = userService; @@ -169,6 +170,7 @@ public class TaggingPanel extends ComponentWithoutSettings userService.addUserStatusEventHandler(this); raceTimesInfoProvider.addRaceTimesInfoProviderListener(this); + generateRandomId(); registerStorageEventHandler(); setCurrentState(State.VIEW); @@ -251,11 +253,21 @@ public class TaggingPanel extends ComponentWithoutSettings */ private void firePrivateTagUpdateEvent() { if (Storage.isSupported()) { - Storage.getLocalStorageIfSupported().setItem(LOCAL_STORAGE_UPDATE_KEY, ""); // Force update + if (Storage.getLocalStorageIfSupported().getItem(LOCAL_STORAGE_UPDATE_KEY).equals(id)) { + // This instance fired the last update. To fire another one we have to change our id + generateRandomId(); + } Storage.getLocalStorageIfSupported().setItem(LOCAL_STORAGE_UPDATE_KEY, id); } } + /** + * Generates a new random ID + */ + private void generateRandomId() { + id = Long.toString(System.currentTimeMillis() * Random.nextInt()); + } + /** * Updates parameters required to save/revoke {@link com.sap.sailing.domain.abstractlog.race.RaceLogEvent events} * to/from {@link com.sap.sailing.domain.abstractlog.race.RaceLog RaceLog}. From f49daaf4b30ecfdfc4e3c83e7ab5d869b77a8a2e Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 26 Jun 2019 00:38:40 +0200 Subject: [PATCH 07/17] bug5081: creating ownership for overall leaderboard when one is created for a leaderboard group Change-Id: Ic582e9c01043d6deefcad02f2878b34b42b5a53c --- .../server/impl/RacingEventServiceImpl.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) 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 9f7a80751f0..6c943953479 100644 --- 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 @@ -28,6 +28,7 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -3025,11 +3026,21 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes private void addOverallLeaderboardToLeaderboardGroup(LeaderboardGroup leaderboardGroup, ScoringScheme scoringScheme, int[] discardThresholds) { - Leaderboard overallLeaderboard = new LeaderboardGroupMetaLeaderboard(leaderboardGroup, scoringScheme, + final Leaderboard overallLeaderboard = new LeaderboardGroupMetaLeaderboard(leaderboardGroup, scoringScheme, new ThresholdBasedResultDiscardingRuleImpl(discardThresholds)); - leaderboardGroup.setOverallLeaderboard(overallLeaderboard); - addLeaderboard(overallLeaderboard); - updateStoredLeaderboard(overallLeaderboard); + // FIXME bug5081 ownership? + getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError( + SecuredDomainType.LEADERBOARD, Leaderboard.getTypeRelativeObjectIdentifier(overallLeaderboard.getName()), + overallLeaderboard.getDisplayName(), + new Callable() { + @Override + public Void call() throws Exception { + leaderboardGroup.setOverallLeaderboard(overallLeaderboard); + addLeaderboard(overallLeaderboard); + updateStoredLeaderboard(overallLeaderboard); + return null; + } + }); } @Override From 23ddb8ebba6f33578068329f788a925ff802ffbc Mon Sep 17 00:00:00 2001 From: Steffen Jacobs Date: Wed, 26 Jun 2019 18:37:19 +0200 Subject: [PATCH 08/17] Bug 5081: used SecurityServiceMockFactory to fix failing tests in RemoveLeaderboardGroupTest --- .../META-INF/MANIFEST.MF | 3 ++- .../server/test/RemoveLeaderboardGroupTest.java | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.server.test/META-INF/MANIFEST.MF b/java/com.sap.sailing.server.test/META-INF/MANIFEST.MF index 895f3906de2..cffcd3c6c76 100644 --- a/java/com.sap.sailing.server.test/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.server.test/META-INF/MANIFEST.MF @@ -24,7 +24,8 @@ Require-Bundle: com.sap.sailing.domain, com.sap.sailing.domain.shared.android, com.sap.sailing.domain.racelogtrackingadapter.testsupport, com.sap.sailing.server.testsupport, - com.sun.jersey;bundle-version="1.17.0" + com.sun.jersey;bundle-version="1.17.0", + com.sap.sse.security.testsupport Import-Package: com.sap.sailing.server.gateway.jaxrs, com.sap.sailing.server.gateway.jaxrs.spi, com.sap.sse.security.userstore.mongodb, diff --git a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/RemoveLeaderboardGroupTest.java b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/RemoveLeaderboardGroupTest.java index 3e10b5d23ae..10cc1678c93 100644 --- a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/RemoveLeaderboardGroupTest.java +++ b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/RemoveLeaderboardGroupTest.java @@ -36,16 +36,25 @@ import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardGroup; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; import com.sap.sse.common.impl.MillisecondsTimePoint; +import com.sap.sse.security.SecurityService; +import com.sap.sse.security.testsupport.SecurityServiceMockFactory; import com.sap.sse.shared.media.ImageDescriptor; import com.sap.sse.shared.media.VideoDescriptor; public class RemoveLeaderboardGroupTest { private RacingEventService server; private Event pfingstbusch; - + @Before public void setUp() { - server = new RacingEventServiceImpl(); + + final SecurityService securityService = SecurityServiceMockFactory.mockSecurityService(); + server = new RacingEventServiceImpl() { + @Override + public SecurityService getSecurityService() { + return securityService; + } + }; List allEvents = new ArrayList<>(); Util.addAll(server.getAllEvents(), allEvents); for (final Event e : allEvents) { From 515f85ee1bcf488542c8ddcba306a8de800c625c Mon Sep 17 00:00:00 2001 From: Steffen Jacobs Date: Wed, 26 Jun 2019 18:39:16 +0200 Subject: [PATCH 09/17] Bug 5081: used SecurityServiceMockFactory to fix failing tests in TestStoringAndRetrievingLeaderboardGroups.java --- .../com.sap.sailing.mongodb.test/META-INF/MANIFEST.MF | 3 ++- .../TestStoringAndRetrievingLeaderboardGroups.java | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.mongodb.test/META-INF/MANIFEST.MF b/java/com.sap.sailing.mongodb.test/META-INF/MANIFEST.MF index 2aa62a6ba5a..2ea264c5696 100644 --- a/java/com.sap.sailing.mongodb.test/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.mongodb.test/META-INF/MANIFEST.MF @@ -35,7 +35,8 @@ Require-Bundle: com.sap.sailing.domain, com.sap.sailing.domain.racelogtrackingadapter, com.sap.sailing.domain.swisstimingreplayadapter, com.sap.sse.security, - com.sap.sse.security.common;bundle-version="1.0.0" + com.sap.sse.security.common;bundle-version="1.0.0", + com.sap.sse.security.testsupport Import-Package: com.sap.sailing.domain.common, com.sap.sailing.domain.common.impl, com.sap.sailing.domain.common.racelog, diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java index 58da6e553f7..60545577ed4 100755 --- a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java @@ -60,6 +60,8 @@ import com.sap.sse.common.Color; import com.sap.sse.common.Util; import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.mongodb.MongoDBService; +import com.sap.sse.security.SecurityService; +import com.sap.sse.security.testsupport.SecurityServiceMockFactory; public class TestStoringAndRetrievingLeaderboardGroups extends AbstractMongoDBTest { private MongoObjectFactory mongoObjectFactory = null; @@ -115,7 +117,14 @@ public class TestStoringAndRetrievingLeaderboardGroups extends AbstractMongoDBTe @Test public void testStoringAndRetrievingLeaderboardGroupWithOverallLeaderboardWithScoreCorrection() throws NoWindException { - RacingEventService racingEventService = new RacingEventServiceImpl(); + + final SecurityService securityService = SecurityServiceMockFactory.mockSecurityService(); + final RacingEventService racingEventService = new RacingEventServiceImpl() { + @Override + public SecurityService getSecurityService() { + return securityService; + } + }; Competitor wolfgangWithoutBoat = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", "KYC", Color.RED, null, null, new TeamImpl("STG", Collections.singleton( new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"), /* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"), From 6b090449eb9b603cad5c19af1abf41778ddc2f3c Mon Sep 17 00:00:00 2001 From: Steffen Jacobs Date: Wed, 26 Jun 2019 18:46:49 +0200 Subject: [PATCH 10/17] Bug 5081: attempted to fix failing tests in MasterDataImportTest --- .../sailing/server/test/MasterDataImportTest.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java index 0679e3a175b..604d5e58141 100644 --- a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java +++ b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java @@ -227,7 +227,12 @@ public class MasterDataImportTest { sourceService = Mockito .spy(new RacingEventServiceImpl(dbFactory, mongoObjectFactory, MediaDBFactory.INSTANCE.getDefaultMediaDB(), EmptyWindStore.INSTANCE, EmptySensorFixStore.INSTANCE, - false)); + false) { + @Override + public SecurityService getSecurityService() { + return securityService; + } + }); masterDataResource = spyResource(new DummyMasterDataRessource(), sourceService); @@ -1879,7 +1884,13 @@ public class MasterDataImportTest { public void testMasterDataImportForMediaTracks() throws MalformedURLException, IOException, InterruptedException, ClassNotFoundException { // Setup source service - RacingEventService sourceService = new RacingEventServiceImpl(); + RacingEventService sourceService = new RacingEventServiceImpl() { + @Override + public SecurityService getSecurityService() { + return securityService; + } + }; + ; Set assignedRaces = new HashSet(); String regattaName1 = "49er"; String regattaName2 = "49er FX"; From 92b402bc68a886d6ef27362141cded2cbba50291 Mon Sep 17 00:00:00 2001 From: Steffen Jacobs Date: Wed, 26 Jun 2019 18:51:48 +0200 Subject: [PATCH 11/17] Bug 5081: used SecurityServiceMockFactory to attempt to fix failing tests in InitialLoadReplicationObjectIdentityTest --- .../META-INF/MANIFEST.MF | 3 ++- ...tialLoadReplicationObjectIdentityTest.java | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.server.replication.test/META-INF/MANIFEST.MF b/java/com.sap.sailing.server.replication.test/META-INF/MANIFEST.MF index bf82f4c7820..abc223329dc 100644 --- a/java/com.sap.sailing.server.replication.test/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.server.replication.test/META-INF/MANIFEST.MF @@ -34,5 +34,6 @@ Require-Bundle: com.sap.sailing.server, org.mongodb.mongo-java-driver;bundle-version="3.6.4", com.sap.sse.security, com.sap.sse.security.common, - com.sun.jersey;bundle-version="1.17.0" + com.sun.jersey;bundle-version="1.17.0", + com.sap.sse.security.testsupport Automatic-Module-Name: com.sap.sailing.server.replication.test diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java index 00c3efede88..3f590051928 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java @@ -81,6 +81,8 @@ import com.sap.sse.common.media.MimeType; import com.sap.sse.replication.ReplicationMasterDescriptor; import com.sap.sse.replication.impl.ReplicationReceiverImpl; import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp.ReplicationServiceTestImpl; +import com.sap.sse.security.SecurityService; +import com.sap.sse.security.testsupport.SecurityServiceMockFactory; public class InitialLoadReplicationObjectIdentityTest extends AbstractServerReplicationTest { private Pair, ReplicationMasterDescriptor> replicationDescriptorPair; @@ -92,10 +94,28 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl @Override public void setUp() throws Exception { persistenceSetUp(/* dropDB */ true); + + final SecurityService securityService = SecurityServiceMockFactory.mockSecurityService(); this.master = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE - .getMongoObjectFactory(testSetUp.mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false); + .getMongoObjectFactory(testSetUp.mongoDBService), + MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, + EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false) { + @Override + public SecurityService getSecurityService() { + return securityService; + } + }; + ; this.replica = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE - .getMongoObjectFactory(testSetUp.mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false); + .getMongoObjectFactory(testSetUp.mongoDBService), + MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, + EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false) { + @Override + public SecurityService getSecurityService() { + return securityService; + } + }; + ; } private void performReplicationSetup() throws Exception { From c4bf938ad985316175badd2b5240e46288c5db19 Mon Sep 17 00:00:00 2001 From: Steffen Jacobs Date: Thu, 27 Jun 2019 10:37:31 +0200 Subject: [PATCH 12/17] Bug 5081: adjusted MasterDataImportTest to reduce number of test failures --- .../com/sap/sailing/server/test/MasterDataImportTest.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java index 604d5e58141..6cf04e0f83a 100644 --- a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java +++ b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java @@ -227,12 +227,7 @@ public class MasterDataImportTest { sourceService = Mockito .spy(new RacingEventServiceImpl(dbFactory, mongoObjectFactory, MediaDBFactory.INSTANCE.getDefaultMediaDB(), EmptyWindStore.INSTANCE, EmptySensorFixStore.INSTANCE, - false) { - @Override - public SecurityService getSecurityService() { - return securityService; - } - }); + false)); masterDataResource = spyResource(new DummyMasterDataRessource(), sourceService); From ccf0a6414f54a4b69d7a76f4bb8019be4fa2f8dc Mon Sep 17 00:00:00 2001 From: Steffen Jacobs Date: Thu, 27 Jun 2019 11:04:38 +0200 Subject: [PATCH 13/17] Bug 5081: fixed failing test in MasterDataImportTest --- .../com/sap/sailing/server/test/MasterDataImportTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java index 6cf04e0f83a..718a33704f8 100644 --- a/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java +++ b/java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/MasterDataImportTest.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import javax.ws.rs.core.Response; @@ -190,6 +191,7 @@ public class MasterDataImportTest { deleteAllDataFromDatabase(); } + @SuppressWarnings("unchecked") @Before public void setUp() { UserGroupImpl defaultTenant = new UserGroupImpl(new UUID(0, 1), "defaultTenant"); @@ -213,6 +215,9 @@ public class MasterDataImportTest { Mockito.doReturn(true).when(securityService).hasCurrentUserOneOfExplicitPermissions( Mockito.any(WithQualifiedObjectIdentifier.class), Matchers. anyVararg()); + Mockito.when(securityService.setOwnershipCheckPermissionForObjectCreationAndRevertOnError(Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any(Callable.class))) + .thenAnswer(i -> i.getArgumentAt(3, Callable.class).call()); Mockito.doReturn(true).when(fakeSubject).isAuthenticated(); From eb9b636a3549557a635bf3fd79eb64caed85effd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Thu, 27 Jun 2019 15:39:11 +0200 Subject: [PATCH 14/17] Fixed issue in RaceLogTrackingCourseDefinitionDialog where removing the third or greater mark would cause an IndexOutOfBoundsException --- .../src/com/sap/sse/gwt/client/celltable/TableWrapper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/TableWrapper.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/TableWrapper.java index 7fcfc3d08ae..7b5c0106046 100755 --- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/TableWrapper.java +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/celltable/TableWrapper.java @@ -110,6 +110,7 @@ public abstract class TableWrapper, SM public void refresh(Iterable newItems) { dataProvider.getList().clear(); Util.addAll(newItems, dataProvider.getList()); + dataProvider.refresh(); dataProvider.flush(); } From 43d4738604d562a0245a980a046474b6b91f1509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Hessenm=C3=BCller?= Date: Fri, 21 Jun 2019 16:22:15 +0200 Subject: [PATCH 15/17] Created icon for orientation change button --- java/com.sap.sailing.gwt.ui/DataMining.css | 5 +++++ .../sap/sailing/gwt/ui/client/StringMessages.java | 1 + .../gwt/ui/client/StringMessages.properties | 1 + .../gwt/ui/client/StringMessages_de.properties | 1 + .../gwt/ui/datamining/DataMiningEntryPoint.java | 14 ++++++++++---- .../gwt/ui/datamining/DataMiningResources.java | 9 +++++++++ .../ui/datamining/images/change_orientation.png | Bin 0 -> 545 bytes 7 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningResources.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/datamining/images/change_orientation.png diff --git a/java/com.sap.sailing.gwt.ui/DataMining.css b/java/com.sap.sailing.gwt.ui/DataMining.css index 9ef6e46c92d..1818050740f 100644 --- a/java/com.sap.sailing.gwt.ui/DataMining.css +++ b/java/com.sap.sailing.gwt.ui/DataMining.css @@ -220,6 +220,11 @@ input.magnifier { top: 7.5px; } +.orientationAnchor { + position: relative; + top: 7.5px; +} + .groupingProvider { padding: 3px 0px; overflow-y: auto; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 4ffdebdde86..56f673eb546 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -962,6 +962,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String raceTimeReachingTooltip(); String raceTimeUpwindTooltip(); String dataMining(); + String changeOrientation(); String hideToolbar(); String showSeriesLeaderboards(); String showOverallLeaderboard(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 3c123240da4..3dbdf9990d6 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -954,6 +954,7 @@ raceTimeUpwindTooltip=Total time traveled upwind in this race noCustomGrouperScriptTextError=The grouper script is empty noGrouperSelectedError=No grouper type is selected dataMining=Data Mining +changeOrientation=Change Orientation hideToolbar=Hide toolbar showSeriesLeaderboards=Show series leaderboards showOverallLeaderboard=Show overall leaderboard diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 3077983fd5f..66a867ca119 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -940,6 +940,7 @@ raceTimeUpwindTooltip=Die in diesem Rennen auf der Kreuz gesegelte Zeit noCustomGrouperScriptTextError=Das Grouper-Skript leer ist noGrouperSelectedError=Kein Gruppierungs-Typ ausgewählt ist dataMining=Data Mining +changeOrientation=Ausrichtung ändern hideToolbar=Toolbar ausblenden showSeriesLeaderboards=Ranglisten der Serie anzeigen showOverallLeaderboard=Gesamtrangliste anzeigen diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java index aa44185c810..b5a60161e28 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java @@ -15,7 +15,8 @@ import com.google.gwt.json.client.JSONParser; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.ServiceDefTarget; -import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.AbstractImagePrototype; +import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.RootLayoutPanel; import com.google.gwt.user.client.ui.SplitLayoutPanel; @@ -58,6 +59,8 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { public static final ComponentResources resources = GWT.create(ComponentResources.class); private static final Logger LOG = Logger.getLogger(DataMiningEntryPoint.class.getName()); + private static final DataMiningResources dataMiningResources = GWT.create(DataMiningResources.class); + private final DataMiningServiceAsync dataMiningService = GWT.create(DataMiningService.class); private DataMiningSession session; @@ -122,14 +125,17 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { queryDefinitionProvider.addControl(new StoredDataMiningQueryPanel(dataProvider)); } - Button orientationButton = new Button("Orientation"); //TODO Use icon or i18n string - orientationButton.addClickHandler(new ClickHandler() { + Anchor orientationAnchor = new Anchor(AbstractImagePrototype.create( + dataMiningResources.orientationIcon()).getSafeHtml()); + orientationAnchor.addStyleName("orientationAnchor"); + orientationAnchor.setTitle(getStringMessages().changeOrientation()); + orientationAnchor.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { setQueryAndResultOrientation(); } }); - queryDefinitionProvider.addControl(orientationButton); + queryDefinitionProvider.addControl(orientationAnchor); /* * Running queries automatically when they've been changed is currently unnecessary, if not even * counterproductive. This removes the query runner settings to prevent that the user can enable the diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningResources.java new file mode 100644 index 00000000000..40f4ab6d6f3 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningResources.java @@ -0,0 +1,9 @@ +package com.sap.sailing.gwt.ui.datamining; + +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.ImageResource; + +interface DataMiningResources extends ClientBundle { + @Source("com/sap/sailing/gwt/ui/datamining/images/change_orientation.png") + ImageResource orientationIcon(); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/datamining/images/change_orientation.png b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/datamining/images/change_orientation.png new file mode 100644 index 0000000000000000000000000000000000000000..b6b6b665ffe1ea7a81a8af2a22fc8a136232789a GIT binary patch literal 545 zcmV++0^a?JP)P000>X1^@s6#OZ}&00004b3#c}2nYxW zdf+++8Zjl5eXbLOAY7rE~La~sL zKuBYgDn+meDbv`Ah=rEvEVNJ;I}tHj_-NADqzO?15d^VFimV8+m@_b0#=9fC>j%TV zbLO1$pK~8Gm;ayx(VoM_iZR<*MjwXpwOv48w9`0+HSDyx7O;+2xQ0P|$Irh(`V0LJ zcwC{9TX>I^0F2>n*cPyv3Y@M0fR81%BUlW;`PPRAD<*EIChlMs&t-Gfbx5w4c!0aT zgus1VkS(O1L7HgbdM_a`gc*$V64FEs-`KxTx~VzT@tbrdOIVfdi?OiX#92Ho_$`Oe zeB2M=HE!c_F=5$eycciNsR#0CEWv z?I2ghx2IF3mhctXkUf%}1*XFO4qLLJsACUL;#ocHn|LM;Dk(@q_FEOswdm*bG!VAE jLd@~7?ci4;clY%Ndpkzr?=IdG00000NkvXXu0mjfx~A#N literal 0 HcmV?d00001 From 03bc005945d7ec4a20886c4b645a89ee4349d543 Mon Sep 17 00:00:00 2001 From: Steffen Jacobs Date: Tue, 2 Jul 2019 18:30:48 +0200 Subject: [PATCH 16/17] Bug 5081: attempt to fix the failing replication test --- .../test/InitialLoadReplicationObjectIdentityTest.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java index 3f590051928..3c42ef15289 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java @@ -17,9 +17,11 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Callable; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl; import com.sap.sailing.domain.abstractlog.race.RaceLog; @@ -90,12 +92,18 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl /** * Drops the test DB. Sets up master and replica, starts the JMS message broker and registers the replica with the master. */ + @SuppressWarnings("unchecked") @Before @Override public void setUp() throws Exception { persistenceSetUp(/* dropDB */ true); final SecurityService securityService = SecurityServiceMockFactory.mockSecurityService(); + + Mockito.when(securityService.setOwnershipCheckPermissionForObjectCreationAndRevertOnError(Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any(Callable.class))) + .thenAnswer(i -> i.getArgumentAt(3, Callable.class).call()); + this.master = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE .getMongoObjectFactory(testSetUp.mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, @@ -105,7 +113,6 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl return securityService; } }; - ; this.replica = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE .getMongoObjectFactory(testSetUp.mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, @@ -115,7 +122,6 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl return securityService; } }; - ; } private void performReplicationSetup() throws Exception { From dd8b0b8beac687405853be161a8919bbdbea2d2f Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 3 Jul 2019 13:27:36 +0200 Subject: [PATCH 17/17] bug5081: fixed test by avoiding Replicable class duplication Change-Id: I8d8a5895f1c7683a06b17735c5f502d95d1f9ead --- ...tialLoadReplicationObjectIdentityTest.java | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java index 3c42ef15289..aa951b1ad21 100755 --- a/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java +++ b/java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/InitialLoadReplicationObjectIdentityTest.java @@ -58,14 +58,19 @@ 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.impl.LowPoint; +import com.sap.sailing.domain.persistence.DomainObjectFactory; +import com.sap.sailing.domain.persistence.MongoObjectFactory; import com.sap.sailing.domain.persistence.PersistenceFactory; +import com.sap.sailing.domain.persistence.media.MediaDB; import com.sap.sailing.domain.persistence.media.MediaDBFactory; import com.sap.sailing.domain.racelog.tracking.EmptySensorFixStore; +import com.sap.sailing.domain.racelog.tracking.SensorFixStore; import com.sap.sailing.domain.ranking.OneDesignRankingMetric; import com.sap.sailing.domain.test.PositionAssert; import com.sap.sailing.domain.test.TrackBasedTest; import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.domain.tracking.WindStore; import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.impl.EmptyWindStore; import com.sap.sailing.server.impl.RacingEventServiceImpl; @@ -89,6 +94,21 @@ import com.sap.sse.security.testsupport.SecurityServiceMockFactory; public class InitialLoadReplicationObjectIdentityTest extends AbstractServerReplicationTest { private Pair, ReplicationMasterDescriptor> replicationDescriptorPair; + private static class RacingEventServiceWithSecurityService extends RacingEventServiceImpl { + private final SecurityService securityService; + + private RacingEventServiceWithSecurityService(final DomainObjectFactory domainObjectFactory, MongoObjectFactory mongoObjectFactory, + MediaDB mediaDB, WindStore windStore, SensorFixStore sensorFixStore, boolean restoreTrackedRaces, SecurityService securityService) { + super(domainObjectFactory, mongoObjectFactory, mediaDB, windStore, sensorFixStore, restoreTrackedRaces); + this.securityService = securityService; + } + + @Override + public SecurityService getSecurityService() { + return securityService; + } + } + /** * Drops the test DB. Sets up master and replica, starts the JMS message broker and registers the replica with the master. */ @@ -97,31 +117,18 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl @Override public void setUp() throws Exception { persistenceSetUp(/* dropDB */ true); - final SecurityService securityService = SecurityServiceMockFactory.mockSecurityService(); - Mockito.when(securityService.setOwnershipCheckPermissionForObjectCreationAndRevertOnError(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(Callable.class))) .thenAnswer(i -> i.getArgumentAt(3, Callable.class).call()); - - this.master = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE + this.master = new RacingEventServiceWithSecurityService(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE .getMongoObjectFactory(testSetUp.mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, - EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false) { - @Override - public SecurityService getSecurityService() { - return securityService; - } - }; - this.replica = new RacingEventServiceImpl(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE + EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false, securityService); + this.replica = new RacingEventServiceWithSecurityService(PersistenceFactory.INSTANCE.getDomainObjectFactory(testSetUp.mongoDBService, DomainFactory.INSTANCE), PersistenceFactory.INSTANCE .getMongoObjectFactory(testSetUp.mongoDBService), MediaDBFactory.INSTANCE.getMediaDB(testSetUp.mongoDBService), EmptyWindStore.INSTANCE, - EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false) { - @Override - public SecurityService getSecurityService() { - return securityService; - } - }; + EmptySensorFixStore.INSTANCE, /* restoreTrackedRaces */ false, securityService); } private void performReplicationSetup() throws Exception {