mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 14:12:11 +00:00
bug4100 Improved settings framework architecture
This commit is contained in:
1 parent
9f3876ba18
commit
eca9002e57
31 files changed
+894
-1251
No files matched your search
+1
-1
@@ -30,8 +30,8 @@ import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sse.gwt.client.shared.perspective.AbstractPerspectiveComposite;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
|
||||
/**
|
||||
* A perspective managing a header with a single leaderboard filling the rest of the screen.
|
||||
|
||||
+4
-8
@@ -14,12 +14,10 @@ import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.gwt.client.mutationobserver.ElementSizeMutationObserver;
|
||||
import com.sap.sse.gwt.client.mutationobserver.ElementSizeMutationObserver.DomMutationCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
|
||||
/**
|
||||
@@ -82,13 +80,11 @@ public abstract class SharedLeaderboardRegattaTabView<T extends AbstractEventReg
|
||||
|
||||
protected ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
|
||||
String placeToken) {
|
||||
final LeaderboardPanelLifecycle lifeCycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final LeaderboardPanelLifecycle lifecycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForEventRegattaLeaderboard(leaderboardName);
|
||||
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
|
||||
userService, storageDefinitionId, placeToken);
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifeCycle, settingsStorageManager);
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
|
||||
lifecycle, userService, storageDefinitionId, placeToken);
|
||||
return componentContext;
|
||||
}
|
||||
}
|
||||
+4
-8
@@ -12,12 +12,10 @@ import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
|
||||
/**
|
||||
@@ -64,13 +62,11 @@ public abstract class SharedLeaderboardEventSeriesTabView<T extends AbstractSeri
|
||||
|
||||
protected ComponentContext<LeaderboardSettings> createLeaderboardComponentContext(String leaderboardName, UserService userService,
|
||||
String placeToken) {
|
||||
final LeaderboardPanelLifecycle lifeCycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final LeaderboardPanelLifecycle lifecycle = new LeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForSeriesOverallLeaderboard(leaderboardName);
|
||||
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
|
||||
userService, storageDefinitionId, placeToken);
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifeCycle, settingsStorageManager);
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
|
||||
lifecycle, userService, storageDefinitionId, placeToken);
|
||||
return componentContext;
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -27,12 +27,10 @@ import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardProxyPanel;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedUserSettingsStorageManager;
|
||||
import com.sap.sse.security.ui.settings.PlaceBasedComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
|
||||
public class EventSeriesLeaderboardsTabView extends Composite implements SeriesTabView<EventSeriesLeaderboardsPlace>,
|
||||
@@ -130,11 +128,9 @@ public class EventSeriesLeaderboardsTabView extends Composite implements SeriesT
|
||||
String placeToken) {
|
||||
final MultiLeaderboardPanelLifecycle lifecycle = new MultiLeaderboardPanelLifecycle(null, StringMessages.INSTANCE);
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForSeriesRegattaLeaderboards(leaderboardName);
|
||||
final SettingsStorageManager<LeaderboardSettings> settingsStorageManager = new PlaceBasedUserSettingsStorageManager<>(
|
||||
userService, storageDefinitionId, placeToken);
|
||||
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifecycle, settingsStorageManager);
|
||||
final ComponentContext<LeaderboardSettings> componentContext = new PlaceBasedComponentContextWithSettingsStorage<>(
|
||||
lifecycle, userService, storageDefinitionId, placeToken);
|
||||
return componentContext;
|
||||
}
|
||||
|
||||
|
||||
+4
-7
@@ -40,13 +40,12 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayStates;
|
||||
import com.sap.sse.gwt.client.shared.components.LinkWithSettingsGenerator;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
import com.sap.sse.gwt.client.shared.perspective.IgnoreLocalSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
import com.sap.sse.security.ui.settings.UserSettingsStorageManager;
|
||||
|
||||
public class RegattaOverviewPanel extends SimplePanel {
|
||||
|
||||
@@ -130,7 +129,7 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
// TODO should we always set ignoreLocalSettings=true when creating links?
|
||||
new SettingsDialog<RegattaRaceStatesSettings>(regattaRaceStatesComponent, stringMessages,
|
||||
new LinkWithSettingsGenerator<>(regattaOverviewContextDefinition,
|
||||
UserSettingsStorageManager.getIgnoreLocalSettings())).show();
|
||||
IgnoreLocalSettings.getIgnoreLocalSettingsFromCurrentUrl())).show();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -154,10 +153,8 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForRegattaOverview(regattaOverviewContextDefinition);
|
||||
final RegattaRaceStatesComponentLifecycle lifecycle = new RegattaRaceStatesComponentLifecycle();
|
||||
final SettingsStorageManager<RegattaRaceStatesSettings> settingsStorageManager = UserSettingsStorageManager
|
||||
.createSettingsStorageManager(userService, storageDefinitionId);
|
||||
final ComponentContext<RegattaRaceStatesSettings> componentContext = new ComponentContextWithSettingsStorage<>(
|
||||
lifecycle, settingsStorageManager);
|
||||
lifecycle, userService, storageDefinitionId);
|
||||
|
||||
regattaRaceStatesComponent = new RegattaRaceStatesComponent(null, componentContext, sailingService, errorReporter,
|
||||
stringMessages,
|
||||
|
||||
+3
-6
@@ -33,11 +33,10 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayStates;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
import com.sap.sse.security.ui.settings.UserSettingsStorageManager;
|
||||
|
||||
public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
public static final long DEFAULT_REFRESH_INTERVAL_MILLIS = 3000l;
|
||||
@@ -117,15 +116,13 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
// make a single live request as the default but don't continue to play by default
|
||||
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForLeaderboard(leaderboardContextDefinition);
|
||||
final UserSettingsStorageManager<PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings>> settingsManager = new UserSettingsStorageManager<>(
|
||||
getUserService(), storageDefinitionId);
|
||||
if (leaderboardType.isMetaLeaderboard()) {
|
||||
// overall
|
||||
|
||||
MetaLeaderboardPerspectiveLifecycle rootComponentLifeCycle = new MetaLeaderboardPerspectiveLifecycle(
|
||||
stringmessages);
|
||||
ComponentContext<PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings>> context = new ComponentContextWithSettingsStorage<>(
|
||||
rootComponentLifeCycle, settingsManager);
|
||||
rootComponentLifeCycle, getUserService(), storageDefinitionId);
|
||||
context.getInitialSettings(
|
||||
new OnSettingsLoadedCallback<PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings>>() {
|
||||
@Override
|
||||
@@ -153,7 +150,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
LeaderboardPerspectiveLifecycle rootComponentLifeCycle = new LeaderboardPerspectiveLifecycle(
|
||||
StringMessages.INSTANCE);
|
||||
ComponentContext<PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings>> context = new ComponentContextWithSettingsStorage<>(
|
||||
rootComponentLifeCycle, settingsManager);
|
||||
rootComponentLifeCycle, getUserService(), storageDefinitionId);
|
||||
context.getInitialSettings(
|
||||
new OnSettingsLoadedCallback<PerspectiveCompositeSettings<LeaderboardPerspectiveOwnSettings>>() {
|
||||
@Override
|
||||
|
||||
+9
-6
@@ -8,12 +8,13 @@ import com.sap.sse.common.settings.util.SettingsMergeUtils;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorageAndPatching;
|
||||
import com.sap.sse.security.ui.settings.SettingsPatch;
|
||||
import com.sap.sse.security.ui.settings.UserSettingsStorageManagerWithPatching;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
|
||||
/**
|
||||
* A specialization of {@link ComponentContextWithSettingsStorageAndPatching} which is specially designed for
|
||||
@@ -32,13 +33,15 @@ public class RaceBoardComponentContext extends ComponentContextWithSettingsStora
|
||||
/**
|
||||
* @param rootLifecycle
|
||||
* The {@link ComponentLifecycle} of the root component/perspective
|
||||
* @param settingsStorageManager
|
||||
* The {@link UserSettingsStorageManagerWithPatching} to be used to access stored settings and to store new settings
|
||||
* @param userService
|
||||
* The service which is used for server-side settings storage
|
||||
* @param storageDefinitionId
|
||||
* The definition for User Settings and Document Settings storage keys
|
||||
*/
|
||||
public RaceBoardComponentContext(
|
||||
RaceBoardPerspectiveLifecycle rootLifecycle,
|
||||
UserSettingsStorageManagerWithPatching<PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings>> settingsStorageManager) {
|
||||
super(rootLifecycle, settingsStorageManager);
|
||||
UserService userService, StorageDefinitionId storageDefinitionId) {
|
||||
super(rootLifecycle, userService, storageDefinitionId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-3
@@ -30,11 +30,10 @@ import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveCompositeSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.DefaultOnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.security.ui.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.security.ui.settings.StorageDefinitionId;
|
||||
import com.sap.sse.security.ui.settings.UserSettingsStorageManagerWithPatching;
|
||||
|
||||
public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
private RaceWithCompetitorsDTO selectedRace;
|
||||
@@ -103,7 +102,7 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
final boolean showChartMarkEditMediaButtonsAndVideo = !DeviceDetector.isMobile();
|
||||
final StorageDefinitionId storageDefinitionId = StorageDefinitionIdFactory.createStorageDefinitionIdForRaceBoard(raceboardContextDefinition);
|
||||
final RaceBoardPerspectiveLifecycle lifeCycle = new RaceBoardPerspectiveLifecycle(raceboardData.getRace().getRaceIdentifier(), StringMessages.INSTANCE);
|
||||
RaceBoardComponentContext componentContext = new RaceBoardComponentContext(lifeCycle, new UserSettingsStorageManagerWithPatching<>(getUserService(), storageDefinitionId));
|
||||
RaceBoardComponentContext componentContext = new RaceBoardComponentContext(lifeCycle, getUserService(), storageDefinitionId);
|
||||
|
||||
componentContext.getInitialSettings(new DefaultOnSettingsLoadedCallback<PerspectiveCompositeSettings<RaceBoardPerspectiveOwnSettings>>() {
|
||||
@Override
|
||||
|
||||
-117
@@ -10,7 +10,6 @@ import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage;
|
||||
@@ -74,127 +73,11 @@ public class SettingsTest extends AbstractSeleniumTest {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
//FIXME just for debugging the loading of raceboard in hudson
|
||||
@Test
|
||||
public void testRaceBoardPageWithoutMode() throws InterruptedException, UnsupportedEncodingException {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
EventConfigurationPanelPO events = adminConsole.goToEvents();
|
||||
events.createEventWithDefaultLeaderboardGroupRegattaAndDefaultLeaderboard(BMW_CUP_EVENT, BMW_CUP_EVENTS_DESC,
|
||||
BMW_VENUE, BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, true, BMW_CUP_REGATTA, BMW_CUP_BOAT_CLASS,
|
||||
BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, false);
|
||||
|
||||
initTrackingForBmwCupRace(adminConsole);
|
||||
|
||||
RaceBoardPage raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA,
|
||||
BMW_CUP_REGATTA, String.format(BMW_RACE, 1));
|
||||
|
||||
MapSettingsPO mapSettings = raceboard.openMapSettings();
|
||||
mapSettings.pressCancel();
|
||||
|
||||
LeaderboardSettingsDialogPO leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog();
|
||||
LeaderboardSettingsPanelPO leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO();
|
||||
leaderboardSettingsPanelPO.getSelectedDetails();
|
||||
leaderboardSettingsDialog.pressCancel();
|
||||
}
|
||||
|
||||
//FIXME just for debugging the loading of raceboard in hudson
|
||||
@Test
|
||||
public void testRaceBoardPageStartAnalysis() throws InterruptedException, UnsupportedEncodingException {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
EventConfigurationPanelPO events = adminConsole.goToEvents();
|
||||
events.createEventWithDefaultLeaderboardGroupRegattaAndDefaultLeaderboard(BMW_CUP_EVENT, BMW_CUP_EVENTS_DESC,
|
||||
BMW_VENUE, BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, true, BMW_CUP_REGATTA, BMW_CUP_BOAT_CLASS,
|
||||
BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, false);
|
||||
|
||||
initTrackingForBmwCupRace(adminConsole);
|
||||
|
||||
RaceBoardPage raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA,
|
||||
BMW_CUP_REGATTA, String.format(BMW_RACE, 1), "START_ANALYSIS");
|
||||
|
||||
MapSettingsPO mapSettings = raceboard.openMapSettings();
|
||||
mapSettings.pressCancel();
|
||||
|
||||
LeaderboardSettingsDialogPO leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog();
|
||||
LeaderboardSettingsPanelPO leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO();
|
||||
leaderboardSettingsPanelPO.getSelectedDetails();
|
||||
leaderboardSettingsDialog.pressCancel();
|
||||
}
|
||||
|
||||
//FIXME just for debugging the loading of raceboard in hudson
|
||||
@Test
|
||||
public void testRaceBoardPageFullAnalysisMode() throws InterruptedException, UnsupportedEncodingException {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
EventConfigurationPanelPO events = adminConsole.goToEvents();
|
||||
events.createEventWithDefaultLeaderboardGroupRegattaAndDefaultLeaderboard(BMW_CUP_EVENT, BMW_CUP_EVENTS_DESC,
|
||||
BMW_VENUE, BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, true, BMW_CUP_REGATTA, BMW_CUP_BOAT_CLASS,
|
||||
BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, false);
|
||||
|
||||
initTrackingForBmwCupRace(adminConsole);
|
||||
|
||||
RaceBoardPage raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA,
|
||||
BMW_CUP_REGATTA, String.format(BMW_RACE, 1), "FULL_ANALYSIS");
|
||||
|
||||
MapSettingsPO mapSettings = raceboard.openMapSettings();
|
||||
mapSettings.pressCancel();
|
||||
|
||||
LeaderboardSettingsDialogPO leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog();
|
||||
LeaderboardSettingsPanelPO leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO();
|
||||
leaderboardSettingsPanelPO.getSelectedDetails();
|
||||
leaderboardSettingsDialog.pressCancel();
|
||||
}
|
||||
|
||||
//FIXME just for debugging the loading of raceboard in hudson
|
||||
@Test
|
||||
public void testRaceBoardPageWinningLanesMode() throws InterruptedException, UnsupportedEncodingException {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
EventConfigurationPanelPO events = adminConsole.goToEvents();
|
||||
events.createEventWithDefaultLeaderboardGroupRegattaAndDefaultLeaderboard(BMW_CUP_EVENT, BMW_CUP_EVENTS_DESC,
|
||||
BMW_VENUE, BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, true, BMW_CUP_REGATTA, BMW_CUP_BOAT_CLASS,
|
||||
BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, false);
|
||||
|
||||
initTrackingForBmwCupRace(adminConsole);
|
||||
|
||||
RaceBoardPage raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA,
|
||||
BMW_CUP_REGATTA, String.format(BMW_RACE, 1), "WINNING_LANES");
|
||||
|
||||
MapSettingsPO mapSettings = raceboard.openMapSettings();
|
||||
mapSettings.pressCancel();
|
||||
|
||||
LeaderboardSettingsDialogPO leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog();
|
||||
LeaderboardSettingsPanelPO leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO();
|
||||
leaderboardSettingsPanelPO.getSelectedDetails();
|
||||
leaderboardSettingsDialog.pressCancel();
|
||||
}
|
||||
|
||||
//FIXME just for debugging the loading of raceboard in hudson
|
||||
@Test
|
||||
public void testRaceBoardPagePlayerMode() throws InterruptedException, UnsupportedEncodingException {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
EventConfigurationPanelPO events = adminConsole.goToEvents();
|
||||
events.createEventWithDefaultLeaderboardGroupRegattaAndDefaultLeaderboard(BMW_CUP_EVENT, BMW_CUP_EVENTS_DESC,
|
||||
BMW_VENUE, BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, true, BMW_CUP_REGATTA, BMW_CUP_BOAT_CLASS,
|
||||
BMW_START_EVENT_TIME, BMW_STOP_EVENT_TIME, false);
|
||||
|
||||
initTrackingForBmwCupRace(adminConsole);
|
||||
|
||||
RaceBoardPage raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA,
|
||||
BMW_CUP_REGATTA, String.format(BMW_RACE, 1), "PLAYER");
|
||||
|
||||
MapSettingsPO mapSettings = raceboard.openMapSettings();
|
||||
mapSettings.pressCancel();
|
||||
|
||||
LeaderboardSettingsDialogPO leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog();
|
||||
LeaderboardSettingsPanelPO leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO();
|
||||
leaderboardSettingsPanelPO.getSelectedDetails();
|
||||
leaderboardSettingsDialog.pressCancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the settings storage of the raceboard. Checks the precedences of url, context specific settings, mode settings and
|
||||
* global settings.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRaceBoardPageSettingsStorage() throws InterruptedException, UnsupportedEncodingException {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
EventConfigurationPanelPO events = adminConsole.goToEvents();
|
||||
|
||||
+2
-2
@@ -61,7 +61,7 @@ public class SettingsDialog<SettingsType extends Settings> extends AbstractSetti
|
||||
new SettingsDialogCallback<>(component, callback));
|
||||
|
||||
if (component.getComponentContext() != null
|
||||
&& component.getComponentContext().hasMakeCustomDefaultSettingsSupport(component)) {
|
||||
&& component.getComponentContext().isStorageSupported(component)) {
|
||||
initMakeDefaultButtons(component, stringMessages);
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,7 @@ public class SettingsDialog<SettingsType extends Settings> extends AbstractSetti
|
||||
@Override
|
||||
public void ok(SettingsType editedSettings) {
|
||||
if (component.getComponentContext() != null
|
||||
&& component.getComponentContext().hasMakeCustomDefaultSettingsSupport(component)) {
|
||||
&& component.getComponentContext().isStorageSupported(component)) {
|
||||
component.getComponentContext().storeSettingsForContext(component, editedSettings, new DummyOnSettingsStoredCallback());
|
||||
}
|
||||
component.updateSettings(editedSettings);
|
||||
|
||||
+2
-3
@@ -27,15 +27,14 @@ public abstract class AbstractPerspectiveComposite<PL extends PerspectiveLifecyc
|
||||
private final Map<String, Component<? extends Settings>> childComponents = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Adds the provided component as a child to this perspective and sets the {@link ComponentTreeNodeInfo}
|
||||
* of the provided component accordingly.
|
||||
* Adds the provided component as a child to the maintained component tree of this perspective.
|
||||
*
|
||||
* @param childComponent The component to be added as a child to this perspective
|
||||
*/
|
||||
protected void addChildComponent(Component<? extends Settings> childComponent) {
|
||||
Component<? extends Settings> old = childComponents.put(childComponent.getId(), childComponent);
|
||||
if (old != null) {
|
||||
throw new IllegalStateException("Child with same id is allready added");
|
||||
throw new IllegalStateException("Child with same id is already added");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+32
-27
@@ -1,27 +1,32 @@
|
||||
package com.sap.sse.gwt.client.shared.perspective;
|
||||
|
||||
import com.sap.sse.common.settings.generic.AbstractGenericSerializableSettings;
|
||||
import com.sap.sse.common.settings.generic.BooleanSetting;
|
||||
|
||||
public class IgnoreLocalSettings extends AbstractGenericSerializableSettings {
|
||||
private static final long serialVersionUID = -282780795782313106L;
|
||||
|
||||
private transient BooleanSetting ignoreLocalSettings;
|
||||
|
||||
public IgnoreLocalSettings() {
|
||||
}
|
||||
|
||||
public IgnoreLocalSettings(boolean ignoreLocalSettings) {
|
||||
this.ignoreLocalSettings.setValue(ignoreLocalSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addChildSettings() {
|
||||
ignoreLocalSettings = new BooleanSetting("ignoreLocalSettings", this, false);
|
||||
}
|
||||
|
||||
public boolean isIgnoreLocalSettings() {
|
||||
return Boolean.TRUE.equals(ignoreLocalSettings.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
package com.sap.sse.gwt.client.shared.perspective;
|
||||
|
||||
import com.sap.sse.common.settings.generic.AbstractGenericSerializableSettings;
|
||||
import com.sap.sse.common.settings.generic.BooleanSetting;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
|
||||
public class IgnoreLocalSettings extends AbstractGenericSerializableSettings {
|
||||
private static final long serialVersionUID = -282780795782313106L;
|
||||
|
||||
private transient BooleanSetting ignoreLocalSettings;
|
||||
|
||||
public IgnoreLocalSettings() {
|
||||
}
|
||||
|
||||
public IgnoreLocalSettings(boolean ignoreLocalSettings) {
|
||||
this.ignoreLocalSettings.setValue(ignoreLocalSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addChildSettings() {
|
||||
ignoreLocalSettings = new BooleanSetting("ignoreLocalSettings", this, false);
|
||||
}
|
||||
|
||||
public boolean isIgnoreLocalSettings() {
|
||||
return Boolean.TRUE.equals(ignoreLocalSettings.getValue());
|
||||
}
|
||||
|
||||
public static IgnoreLocalSettings getIgnoreLocalSettingsFromCurrentUrl() {
|
||||
return new SettingsToUrlSerializer().deserializeFromCurrentLocation(new IgnoreLocalSettings());
|
||||
}
|
||||
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
package com.sap.sse.gwt.client.shared.settings;
|
||||
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
|
||||
/**
|
||||
* Basic implementation for {@link SettingsBuildingPipeline} which provides a implementation of few methods.
|
||||
* It is highly recommended to inherit all other implementations from this class.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @see SettingsBuildingPipeline
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSettingsBuildingPipeline implements SettingsBuildingPipeline {
|
||||
|
||||
/**
|
||||
* Conversion helper which is used by this instance for type conversion/serialization
|
||||
* between settings objects and JSON Strings.
|
||||
*/
|
||||
protected final SettingsStringConverter settingsStringConverter;
|
||||
|
||||
/**
|
||||
* Constructs an instance with {@link SettingsStringConverter} as conversion helper between
|
||||
* settings objects and its JSON representation.
|
||||
*/
|
||||
public AbstractSettingsBuildingPipeline() {
|
||||
this(new SettingsStringConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance with a custom conversion helper between
|
||||
* settings objects and its JSON representation.
|
||||
*/
|
||||
public AbstractSettingsBuildingPipeline(SettingsStringConverter settingsStringConverter) {
|
||||
this.settingsStringConverter = settingsStringConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public<S extends Settings> S getSettingsObject(S defaultSettings, SettingsStrings settingsStrings) {
|
||||
SettingsJsons settingsJsons = settingsStringConverter.convertToSettingsJson(settingsStrings);
|
||||
return getSettingsObject(defaultSettings, settingsJsons);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <S extends Settings> S getSettingsObject(S defaultSettings) {
|
||||
return getSettingsObject(defaultSettings, new SettingsJsons(null, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SettingsStringConverter getSettingsStringConverter() {
|
||||
return settingsStringConverter;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -37,7 +37,7 @@ public interface ComponentContext<S extends Settings> {
|
||||
|
||||
/**
|
||||
* Stores the provided {@link Settings} of the provided {@link Component} as "User Settings" globally. Make sure to
|
||||
* call this method only when {@link #hasMakeCustomDefaultSettingsSupport(Component)} method returns {@code true}
|
||||
* call this method only when {@link #isStorageSupported(Component)} method returns {@code true}
|
||||
* for the provided {@link Component}.
|
||||
*
|
||||
* @param component
|
||||
@@ -50,7 +50,7 @@ public interface ComponentContext<S extends Settings> {
|
||||
|
||||
/**
|
||||
* Stores the provided {@link Settings} of the provided {@link Component} as "Document Settings" (old term "Context specific Settings") for the current context. Make sure to
|
||||
* call this method only when {@link #hasMakeCustomDefaultSettingsSupport(Component)} method returns {@code true}
|
||||
* call this method only when {@link #isStorageSupported(Component)} method returns {@code true}
|
||||
* for the provided {@link Component}.
|
||||
*
|
||||
* @param component
|
||||
@@ -79,7 +79,7 @@ public interface ComponentContext<S extends Settings> {
|
||||
* <b>AND</b> the {@link ComponentContext} implementation has settings
|
||||
* storage support
|
||||
*/
|
||||
boolean hasMakeCustomDefaultSettingsSupport(Component<?> component);
|
||||
boolean isStorageSupported(Component<?> component);
|
||||
|
||||
/**
|
||||
* Gets initial settings and passes these settings to the provided callback.
|
||||
|
||||
-335
@@ -1,335 +0,0 @@
|
||||
package com.sap.sse.gwt.client.shared.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.common.settings.generic.GenericSerializableSettings;
|
||||
import com.sap.sse.common.settings.generic.SettingsMap;
|
||||
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
|
||||
import com.sap.sse.common.settings.util.SettingsMergeUtils;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
|
||||
/**
|
||||
* Manages all the default/initial settings of a component/perspective and its subcomponents if there are any. It supplies
|
||||
* components with initial settings and determines whether the settings of components are storable or not. This
|
||||
* implementation provides settings storage support if the storable settings either implement {@link SettingsMap} or
|
||||
* {@link GenericSerializableSettings}. There are two kinds of settings which are stored separately - <b>User
|
||||
* Settings</b> (old term "Global Settings") and <b>Document Settings</b> (old term "Context specific Settings").
|
||||
* <dl>
|
||||
* <dt>Document Settings</dt>
|
||||
* <dd>The settings are stored only for the current context (e.g. a race presented in a RaceBoard). This settings are not considered in any other context. See {@link #storeSettingsForContext(Component, Settings, OnSettingsStoredCallback)}</dd>
|
||||
*
|
||||
* <dt>User Settings</dt>
|
||||
* <dd>The settings are stored for a component/perspective context-independently and may effect a different context presented by the same perspective/component, e.g. a different race in a RaceBoard. See {@link #makeSettingsDefault(Component, Settings, OnSettingsStoredCallback)}</dd>
|
||||
* </dl>
|
||||
* That means that Document Settings are stored per context (e.g. race in RaceBoard) whereas User Settings are
|
||||
* stored globally for all possible contexts (e.g. for the whole RaceBoard independently from selected race).
|
||||
*
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
* @see ComponentContext
|
||||
*
|
||||
* @param <S>
|
||||
* The {@link Settings} type of the settings of the root component/perspective containing all the settings
|
||||
* for itself and its subcomponents
|
||||
*
|
||||
*/
|
||||
public class ComponentContextWithSettingsStorage<S extends Settings> extends SimpleComponentContext<S> {
|
||||
|
||||
/**
|
||||
* Settings which have been already constructed, or {@code null} if settings have not been initialized yet.
|
||||
*/
|
||||
protected S cachedRootComponentSettings = null;
|
||||
|
||||
/**
|
||||
* Manages the persistence layer of settings.
|
||||
*/
|
||||
protected final SettingsStorageManager<S> settingsStorageManager;
|
||||
|
||||
/**
|
||||
* @param rootLifecycle
|
||||
* The {@link ComponentLifecycle} of the root component/perspective
|
||||
* @param settingsStorageManager
|
||||
* The {@link SettingsStorageManager} to be used to access stored settings and to store new settings
|
||||
*/
|
||||
public ComponentContextWithSettingsStorage(ComponentLifecycle<S> rootLifecycle,
|
||||
SettingsStorageManager<S> settingsStorageManager) {
|
||||
super(rootLifecycle);
|
||||
this.settingsStorageManager = settingsStorageManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the initial settings and caches them for further calls of
|
||||
* {@link #getInitialSettings(OnSettingsLoadedCallback)} and {@link #getInitialSettingsForComponent(Component, OnSettingsLoadedCallback)}.
|
||||
*/
|
||||
public void initialize() {
|
||||
getInitialSettings(new OnSettingsLoadedCallback<S>() {
|
||||
@Override
|
||||
public void onError(Throwable caught, S fallbackDefaultSettings) {}
|
||||
@Override
|
||||
public void onSuccess(S settings) {}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets initial settings and passes these settings to the provided callback.
|
||||
* The provided callback gets called when initial/default settings are available. The callback may be called after a delay, e.g. after the settings have been retrieved from a server,
|
||||
* or immediately, e.g. when the implementation does not query information from server.
|
||||
* This method produces no side-effects if it gets called multiple times. After this method has been called for the first time, subsequent calls will not produce any server round-trips
|
||||
* or LocalStorage accesses due to its internal caching.
|
||||
*
|
||||
* @param settingsReceiverCallback The callback which supplies the caller with initial settings
|
||||
*/
|
||||
@Override
|
||||
public void getInitialSettings(final OnSettingsLoadedCallback<S> callback) {
|
||||
if(cachedRootComponentSettings == null) {
|
||||
S systemDefaultSettings = rootLifecycle.createDefaultSettings();
|
||||
settingsStorageManager.retrieveDefaultSettings(systemDefaultSettings, new OnSettingsLoadedCallback<S>() {
|
||||
|
||||
@Override
|
||||
public void onError(Throwable caught, S fallbackDefaultSettings) {
|
||||
cachedRootComponentSettings = fallbackDefaultSettings;
|
||||
callback.onError(caught, fallbackDefaultSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(S settings) {
|
||||
cachedRootComponentSettings = settings;
|
||||
callback.onSuccess(settings);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback.onSuccess(cachedRootComponentSettings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets initial settings of the provided component and passes these settings to the provided callback.
|
||||
* The provided callback gets called when initial/default settings are available. The callback may be called after a delay, e.g. after the settings have been retrieved from a server,
|
||||
* or immediately, e.g. when the implementation does not query information from server.
|
||||
* This method produces no side-effects if it gets called multiple times.
|
||||
* @param settingsReceiverCallback The callback which supplies the caller with initial settings
|
||||
*/
|
||||
@Override
|
||||
public <CS extends Settings> void getInitialSettingsForComponent(final Component<CS> component, final OnSettingsLoadedCallback<CS> callback) {
|
||||
OnSettingsLoadedCallback<S> internalCallback = new OnSettingsLoadedCallback<S>() {
|
||||
|
||||
@Override
|
||||
public void onError(Throwable caught, S fallbackDefaultSettings) {
|
||||
CS componentFallbackSettings = ComponentUtils.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(component.getPath()), fallbackDefaultSettings);
|
||||
callback.onError(caught, componentFallbackSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(S settings) {
|
||||
CS componentSettings = ComponentUtils.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(component.getPath()), settings);
|
||||
callback.onSuccess(componentSettings);
|
||||
}
|
||||
};
|
||||
getInitialSettings(internalCallback);
|
||||
}
|
||||
|
||||
protected void invalidateCachedSettings() {
|
||||
cachedRootComponentSettings = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the {@link Settings} of the provided {@link Component} are
|
||||
* storable and whether the underlying implementation supports
|
||||
* {@link #makeSettingsDefault(Component, Settings)} calls for it.
|
||||
*
|
||||
* @param component The component with potentially storable settings
|
||||
* @return {@code true} if the settings of the component are storable
|
||||
* <b>AND</b> the {@link ComponentContext} implementation has settings
|
||||
* storage support
|
||||
*/
|
||||
@Override
|
||||
public boolean hasMakeCustomDefaultSettingsSupport(Component<?> component) {
|
||||
if (!component.hasSettings()) {
|
||||
return false;
|
||||
}
|
||||
if(!settingsStorageManager.supportsStore()) {
|
||||
return false;
|
||||
}
|
||||
Settings settings = component.getSettings();
|
||||
if (settings instanceof SettingsMap || settings instanceof GenericSerializableSettings) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the provided {@link Settings} of the provided {@link Component} as "User Settings" globally. Make sure to
|
||||
* call this method only when {@link #hasMakeCustomDefaultSettingsSupport(Component)} method returns {@code true}
|
||||
* for the provided {@link Component}.
|
||||
*
|
||||
* @param component
|
||||
* The component which corresponds to the provided {@link Settings}
|
||||
* @param newDefaultSettings
|
||||
* The {@link Settings} to be stored
|
||||
* @param onSettingsStoredCallback The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
@Override
|
||||
public<CS extends Settings> void makeSettingsDefault(Component<CS> component, CS newDefaultSettings, final OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
invalidateCachedSettings();
|
||||
ComponentLifecycle<CS> targetLifecycle = ComponentUtils.determineLifecycle(new ArrayList<>(component.getPath()), rootLifecycle);
|
||||
CS globalSettings = targetLifecycle.extractGlobalSettings(newDefaultSettings);
|
||||
updateGlobalSettings(component.getPath(), globalSettings, onSettingsStoredCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the provided {@link Settings} of the provided {@link Component} as "Document Settings" (old term "Context specific Settings") for the current context. Make sure to
|
||||
* call this method only when {@link #hasMakeCustomDefaultSettingsSupport(Component)} method returns {@code true}
|
||||
* for the provided {@link Component}.
|
||||
*
|
||||
* @param component
|
||||
* The component which corresponds to the provided {@link Settings}
|
||||
* @param newSettings
|
||||
* The {@link Settings} to be stored
|
||||
* @param onSettingsStoredCallback The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
@Override
|
||||
public<CS extends Settings> void storeSettingsForContext(Component<CS> component, CS newSettings, OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
invalidateCachedSettings();
|
||||
ComponentLifecycle<CS> targetLifecycle = ComponentUtils.determineLifecycle(new ArrayList<>(component.getPath()), rootLifecycle);
|
||||
CS contextSpecificSettings = targetLifecycle.extractContextSpecificSettings(newSettings);
|
||||
updateContextSpecificSettings(component.getPath(), contextSpecificSettings, onSettingsStoredCallback);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Patches the settings tree with the new settings provided. The settings node with the provided path
|
||||
* is going to be created/replaced with the new settings.
|
||||
*
|
||||
* @param root The root node of the settings tree
|
||||
* @param path The path of the node to create/update
|
||||
* @param newSettings The new settings with that the target node in the settings tree is going to be updated
|
||||
* @param pipelineLevel The scope of settings used for settings storage (e.g. User Settings, or Document Settings)
|
||||
* @return The patched settings located by provided path as JSON
|
||||
*/
|
||||
private JSONObject patchJsonObject(JSONObject root, List<String> path, Settings newSettings, PipelineLevel pipelineLevel) {
|
||||
newSettings = cloneStorableSettings(newSettings, path);
|
||||
return patchJsonObject(root, path, Collections.unmodifiableList(new ArrayList<>(path)), newSettings, pipelineLevel);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private<CS extends Settings> CS cloneStorableSettings(CS settingsToClone, List<String> path) {
|
||||
CS clonedSettings = ComponentUtils.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(path), rootLifecycle.createDefaultSettings());
|
||||
if(clonedSettings instanceof GenericSerializableSettings) {
|
||||
GenericSerializableSettings newSettings = (GenericSerializableSettings) clonedSettings;
|
||||
GenericSerializableSettings originalSettings = (GenericSerializableSettings) settingsToClone;
|
||||
SettingsDefaultValuesUtils.keepDefaults(originalSettings, newSettings);
|
||||
SettingsMergeUtils.setValues(originalSettings, newSettings);
|
||||
clonedSettings = (CS) newSettings;
|
||||
}
|
||||
//TODO maybe add support for SettingsMap? Currently, SettingsMap is never provided as parameter to this method
|
||||
return clonedSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper method for {@link #patchJsonObject(JSONObject, List, Settings, PipelineLevel)}
|
||||
*
|
||||
* @param root
|
||||
* @param path
|
||||
* @param originalPath
|
||||
* @param newSettings
|
||||
* @param pipelineLevel
|
||||
* @return
|
||||
*/
|
||||
private JSONObject patchJsonObject(JSONObject root, List<String> path, List<String> originalPath, Settings newSettings, PipelineLevel pipelineLevel) {
|
||||
if(path.isEmpty()) {
|
||||
return (JSONObject) settingsStorageManager.settingsToJSON(newSettings, pipelineLevel, originalPath);
|
||||
}
|
||||
if (root == null) {
|
||||
root = new JSONObject();
|
||||
}
|
||||
String current = path.remove(path.size() - 1);
|
||||
// we need to go further
|
||||
if (!path.isEmpty()) {
|
||||
JSONValue child = root.get(current);
|
||||
boolean haskey = root.containsKey(current);
|
||||
if (child == null || child.isObject() == null) {
|
||||
if (haskey) {
|
||||
GWT.log("Warning: replacing some subtree element that is wrong type!");
|
||||
}
|
||||
child = new JSONObject();
|
||||
root.put(current, child);
|
||||
}
|
||||
return patchJsonObject(child.isObject(), path, originalPath, newSettings, pipelineLevel);
|
||||
} else {
|
||||
JSONValue json = settingsStorageManager.settingsToJSON(newSettings, pipelineLevel, originalPath);
|
||||
root.put(current, json);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the User Settings' tree with the new settings provided. The settings node with the provided path
|
||||
* is going to be created/replaced with the new settings. This method may produce a server round-trip
|
||||
* if the user is logged in.
|
||||
*
|
||||
* @param path The path of the settings' node to create/update
|
||||
* @param globalSettings User Settings which corresponds to the provided path
|
||||
* @param onSettingsStoredCallback The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
private void updateGlobalSettings(final ArrayList<String> path, final Settings globalSettings,
|
||||
final OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
settingsStorageManager.retrieveSettingsJsons(new AsyncCallback<SettingsJsons>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(SettingsJsons result) {
|
||||
final JSONObject patchedGlobalSettings = patchJsonObject(result.getGlobalSettingsJson(), new ArrayList<>(path),
|
||||
globalSettings, PipelineLevel.GLOBAL_DEFAULTS);
|
||||
settingsStorageManager.storeGlobalSettingsJson(patchedGlobalSettings, onSettingsStoredCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
onSettingsStoredCallback.onError(caught);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the Document Settings' tree with the new settings provided. The settings node with the provided path
|
||||
* is going to be created/replaced with the new settings. This method may produce a server round-trip
|
||||
* if the user is logged in.
|
||||
*
|
||||
* @param path The path of the settings' node to create/update
|
||||
* @param contextSpecificSettings Document Settings which corresponds to the provided path
|
||||
* @param onSettingsStoredCallback The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
private void updateContextSpecificSettings(final ArrayList<String> path, final Settings contextSpecificSettings,
|
||||
final OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
settingsStorageManager.retrieveSettingsJsons(new AsyncCallback<SettingsJsons>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(SettingsJsons result) {
|
||||
final JSONObject patchedContextSpecificSettings = patchJsonObject(result.getContextSpecificSettingsJson(), new ArrayList<>(path),
|
||||
contextSpecificSettings, PipelineLevel.CONTEXT_SPECIFIC_DEFAULTS);
|
||||
settingsStorageManager.storeContextSpecificSettingsJson(patchedContextSpecificSettings, onSettingsStoredCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
onSettingsStoredCallback.onError(caught);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
settingsStorageManager.dispose();
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
package com.sap.sse.gwt.client.shared.settings;
|
||||
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
|
||||
public interface OnSettingsLoadedCallback<S extends Settings> {
|
||||
public interface OnSettingsLoadedCallback<S> {
|
||||
void onError(Throwable caught, S fallbackDefaultSettings);
|
||||
void onSuccess(S settings);
|
||||
}
|
||||
+5
-36
@@ -11,48 +11,25 @@ import com.sap.sse.common.settings.Settings;
|
||||
* implementation of this interface to define the desired way of how the settings are constructed from its persisted
|
||||
* JSON representation, and how the settings are transformed back into its persisted JSON representation.
|
||||
* The pipeline is being used in {@link SettingsStorageManager} when it loads and stores settings.
|
||||
* It is highly recommended to use at least {@link AbstractSettingsBuildingPipeline} as basic class for
|
||||
* implementation of this interface.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @param <S> The type of settings representation
|
||||
* @see SettingsStorageManager
|
||||
* @see AbstractSettingsBuildingPipeline
|
||||
*
|
||||
*/
|
||||
public interface SettingsBuildingPipeline {
|
||||
public interface SettingsBuildingPipeline<S> {
|
||||
|
||||
/**
|
||||
* Constructs a settings object by means of provided defaultSettings and persisted representations of
|
||||
* User Settings and Document Settings.
|
||||
* Constructs a settings object by means of provided defaultSettings and persisted representations of Settings.
|
||||
* This method implements the settings construction pipeline for a settings object which is used for settings loading operations.
|
||||
*
|
||||
* @param defaultSettings The basic settings to be used
|
||||
* @param settingsJsons The persisted representation of User Settings and Document Settings
|
||||
* @param settingsRepresentation The persisted representation of Settings
|
||||
* @return The constructed settings object
|
||||
*/
|
||||
<S extends Settings> S getSettingsObject(S defaultSettings, SettingsJsons settingsJsons);
|
||||
|
||||
/**
|
||||
* Constructs a settings object by means of provided defaultSettings and persisted representations of
|
||||
* User Settings and Document Settings.
|
||||
* This method implements the settings construction pipeline for a settings object which is used for settings loading operations.
|
||||
*
|
||||
* @param defaultSettings The basic settings to be used
|
||||
* @param settingsJsons The persisted representation of User Settings and Document Settings
|
||||
* @return The constructed settings object
|
||||
*/
|
||||
<S extends Settings> S getSettingsObject(S defaultSettings, SettingsStrings settingsStrings);
|
||||
|
||||
/**
|
||||
* Constructs a settings object by means of provided defaultSettings without considering
|
||||
* User Settings and Document Settings.
|
||||
* This method implements the settings construction pipeline for a settings object which is used for settings loading operations.
|
||||
*
|
||||
* @param defaultSettings The basic settings to be used
|
||||
* @return The constructed settings object
|
||||
*/
|
||||
<S extends Settings> S getSettingsObject(S defaultSettings);
|
||||
<CS extends Settings> CS getSettingsObject(CS defaultSettings, S settingsRepresentation);
|
||||
|
||||
/**
|
||||
* Converts the provided settings according the storage scope and path of the provided settings in the settings tree.
|
||||
@@ -65,12 +42,4 @@ public interface SettingsBuildingPipeline {
|
||||
*/
|
||||
JSONValue getJsonObject(Settings settings, PipelineLevel pipelineLevel, List<String> path);
|
||||
|
||||
/**
|
||||
* Gets the {@link SettingsStringConverter} which is used by this instance for type conversion/serialization
|
||||
* between settings objects and JSON Strings.
|
||||
*
|
||||
* @return The conversion helper instance used by this pipeline
|
||||
*/
|
||||
SettingsStringConverter getSettingsStringConverter();
|
||||
|
||||
}
|
||||
+12
-25
@@ -9,22 +9,21 @@ import com.sap.sse.gwt.settings.SettingsToJsonSerializerGWT;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
|
||||
/**
|
||||
* Conversion helper which is used by this instance for type conversion/serialization
|
||||
* between settings objects and JSON Strings. The class encapsulates all serializers
|
||||
* which are required for serialization and deserialization and provides methods
|
||||
* for an indirect serialization/deserialization functionality required by
|
||||
* {@link SettingsBuildingPipeline} and {@link SettingsStorageManager} implementations.
|
||||
* Conversion helper which is used by this instance for type conversion/serialization between settings objects and JSON
|
||||
* Strings. The class encapsulates all serializers which are required for serialization and deserialization and provides
|
||||
* methods for an indirect serialization/deserialization functionality required by {@link SettingsBuildingPipeline} and
|
||||
* {@link ComponentContext} implementations.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
*/
|
||||
public class SettingsStringConverter {
|
||||
public class SettingsSerializationHelper {
|
||||
|
||||
private final SettingsToUrlSerializer urlSerializer = new SettingsToUrlSerializer();
|
||||
private final SettingsToJsonSerializerGWT jsonSerializer = new SettingsToJsonSerializerGWT();
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public<S extends Settings> S deserializeFromCurrentUrl(S defaultSettings) {
|
||||
public <S extends Settings> S deserializeFromCurrentUrl(S defaultSettings) {
|
||||
if (defaultSettings instanceof GenericSerializableSettings) {
|
||||
defaultSettings = (S) urlSerializer
|
||||
.deserializeFromCurrentLocation((GenericSerializableSettings) defaultSettings);
|
||||
@@ -34,9 +33,9 @@ public class SettingsStringConverter {
|
||||
}
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public<S extends Settings> S deserializeFromJson(S defaultSettings, JSONObject jsonToDeserialize) {
|
||||
public <S extends Settings> S deserializeFromJson(S defaultSettings, JSONObject jsonToDeserialize) {
|
||||
if (defaultSettings instanceof GenericSerializableSettings) {
|
||||
defaultSettings = (S) jsonSerializer.deserialize((GenericSerializableSettings) defaultSettings,
|
||||
jsonToDeserialize);
|
||||
@@ -46,31 +45,19 @@ public class SettingsStringConverter {
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
public SettingsJsons convertToSettingsJson(SettingsStrings settingsStrings) {
|
||||
JSONObject globalSettingsJson = convertStringToJson(settingsStrings.getGlobalSettingsString());
|
||||
JSONObject contextSpecificSettingsJson = convertStringToJson(settingsStrings.getContextSpecificSettingsString());
|
||||
return new SettingsJsons(globalSettingsJson, contextSpecificSettingsJson);
|
||||
}
|
||||
|
||||
public JSONObject convertStringToJson(String str) {
|
||||
return str == null ? null : jsonSerializer.parseStringToJsonObject(str);
|
||||
}
|
||||
|
||||
|
||||
public String convertJsonToString(JSONObject json) {
|
||||
return json == null ? null : jsonSerializer.jsonObjectToString(json);
|
||||
}
|
||||
|
||||
public SettingsStrings convertToSettingsStrings(SettingsJsons settingsJsons) {
|
||||
String globalSettingsString = convertJsonToString(settingsJsons.getGlobalSettingsJson());
|
||||
String contextSpecificSettingsString = convertJsonToString(settingsJsons.getContextSpecificSettingsJson());
|
||||
return new SettingsStrings(globalSettingsString, contextSpecificSettingsString);
|
||||
}
|
||||
|
||||
|
||||
public JSONValue serializeFromSettingsObject(Settings newSettings) {
|
||||
if (newSettings instanceof GenericSerializableSettings) {
|
||||
return jsonSerializer.serialize((GenericSerializableSettings) newSettings);
|
||||
}
|
||||
throw new IllegalStateException("Requested save of settings that is not Serializable!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+27
-56
@@ -1,11 +1,5 @@
|
||||
package com.sap.sse.gwt.client.shared.settings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.common.settings.generic.GenericSerializableSettings;
|
||||
|
||||
/**
|
||||
@@ -16,66 +10,43 @@ import com.sap.sse.common.settings.generic.GenericSerializableSettings;
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @param <S> The {@link Settings} type of the settings of the root component/perspective containing all the settings for itself and its subcomponents
|
||||
* @param <S> The type of settings representation
|
||||
* @see ComponentContextWithSettingsStorage
|
||||
* @see GenericSerializableSettings
|
||||
*/
|
||||
public interface SettingsStorageManager<S extends Settings> {
|
||||
public interface SettingsStorageManager<S> {
|
||||
|
||||
/**
|
||||
* Tells whether the underlying implementation offers persistence for settings, or not.
|
||||
*
|
||||
* @return {@code True} if settings storage is supported, otherwise {@code false}
|
||||
*/
|
||||
boolean supportsStore();
|
||||
// /**
|
||||
// * Tells whether storage of settings is supported, or not.
|
||||
// *
|
||||
// * @return {@code True} if settings storage is supported, otherwise {@code false}
|
||||
// */
|
||||
// boolean supportsStore();
|
||||
|
||||
/**
|
||||
* Retrieves the {@link Settings} of the root component using the provided callback.
|
||||
* Depending on the storage media, the callback may be called whether synchronously
|
||||
* or asynchronously.
|
||||
*
|
||||
* @param defaultSettings The system default settings for the root component
|
||||
* @param asyncCallback The callback to be called when the settings have been retrieved
|
||||
* from the settings storage
|
||||
*/
|
||||
void retrieveDefaultSettings(S defaultSettings,
|
||||
OnSettingsLoadedCallback<S> asyncCallback);
|
||||
|
||||
/**
|
||||
* Stores provided settings as User Settings (old term "Global Settings"). Only the delta between default settings and provided settings
|
||||
* will be stored.
|
||||
*
|
||||
* @param globalSettingsJson The settings to store
|
||||
* @param onSettingsStoredCallback The callback which is called when the settings storage process gets finished
|
||||
*/
|
||||
void storeGlobalSettingsJson(JSONObject globalSettingsJson, OnSettingsStoredCallback onSettingsStoredCallback);
|
||||
|
||||
/**
|
||||
* Stores provided settings as Document Settings (old term "Context specific Settings"). Only the delta between default settings and provided settings
|
||||
* will be stored.
|
||||
*
|
||||
* @param contextSpecificSettingsJson The settings to store
|
||||
* @param onSettingsStoredCallback The callback which is called when the settings storage process gets finished
|
||||
*/
|
||||
void storeContextSpecificSettingsJson(JSONObject contextSpecificSettingsJson,
|
||||
OnSettingsStoredCallback onSettingsStoredCallback);
|
||||
|
||||
/**
|
||||
* Converts the provided settings object to JSON.
|
||||
*
|
||||
* @param newSettings The settings to convert
|
||||
* @param pipelineLevel The pipeline level indicating whether the provided settings should be converted for Document Settings storage, or User Settings storage
|
||||
* @param path The path of the corresponding settings in the settings tree according to the component which the provided settings belong to
|
||||
* @return The converted settings as JSON
|
||||
*/
|
||||
JSONValue settingsToJSON(Settings newSettings, PipelineLevel pipelineLevel, List<String> path);
|
||||
// /**
|
||||
// * Converts the provided settings object to JSON.
|
||||
// *
|
||||
// * @param newSettings The settings to convert
|
||||
// * @param pipelineLevel The pipeline level indicating whether the provided settings should be converted for Document Settings storage, or User Settings storage
|
||||
// * @param path The path of the corresponding settings in the settings tree according to the component which the provided settings belong to
|
||||
// * @return The converted settings as JSON
|
||||
// */
|
||||
// JSONValue settingsToJSON(Settings newSettings, PipelineLevel pipelineLevel, List<String> path);
|
||||
|
||||
/**
|
||||
* Retrieves the stored JSON representations of Document Settings and User Settings which get packed together in {@link SettingsJsons}.
|
||||
*
|
||||
* @param asyncCallback The callback which gets called when the persisted settings representation has been retrieved
|
||||
* @param callback The callback which gets called when the persisted settings representation has been retrieved
|
||||
*/
|
||||
void retrieveSettingsJsons(AsyncCallback<SettingsJsons> asyncCallback);
|
||||
void retrieveSettingsRepresentation(OnSettingsLoadedCallback<S> callback);
|
||||
|
||||
/**
|
||||
* Stores provided settings representation.
|
||||
*
|
||||
* @param settingsRepresentation The settings to store
|
||||
* @param onSettingsStoredCallback The callback which is called when the settings storage process gets finished
|
||||
*/
|
||||
void storeSettingsRepresentation(S settingsRepresentation, OnSettingsStoredCallback onSettingsStoredCallback);
|
||||
|
||||
/**
|
||||
* Releases all resources and listener registrations acquired by this instance.
|
||||
|
||||
+404
@@ -0,0 +1,404 @@
|
||||
package com.sap.sse.security.ui.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.common.settings.generic.GenericSerializableSettings;
|
||||
import com.sap.sse.common.settings.generic.SettingsMap;
|
||||
import com.sap.sse.common.settings.util.SettingsDefaultValuesUtils;
|
||||
import com.sap.sse.common.settings.util.SettingsMergeUtils;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
import com.sap.sse.gwt.client.shared.perspective.IgnoreLocalSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentUtils;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsStoredCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsBuildingPipeline;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsSerializationHelper;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStrings;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
/**
|
||||
* Manages all the default/initial settings of a component/perspective and its subcomponents if there are any. It
|
||||
* supplies components with initial settings and determines whether the settings of components are storable or not. This
|
||||
* implementation provides settings storage support if the storable settings either implement {@link SettingsMap} or
|
||||
* {@link GenericSerializableSettings}. There are two kinds of settings which are stored separately - <b>User
|
||||
* Settings</b> (old term "Global Settings") and <b>Document Settings</b> (old term "Context specific Settings").
|
||||
* <dl>
|
||||
* <dt>Document Settings</dt>
|
||||
* <dd>The settings are stored only for the current context (e.g. a race presented in a RaceBoard). This settings are
|
||||
* not considered in any other context. See
|
||||
* {@link #storeSettingsForContext(Component, Settings, OnSettingsStoredCallback)}</dd>
|
||||
*
|
||||
* <dt>User Settings</dt>
|
||||
* <dd>The settings are stored for a component/perspective context-independently and may effect a different context
|
||||
* presented by the same perspective/component, e.g. a different race in a RaceBoard. See
|
||||
* {@link #makeSettingsDefault(Component, Settings, OnSettingsStoredCallback)}</dd>
|
||||
* </dl>
|
||||
* That means that Document Settings are stored per context (e.g. race in RaceBoard) whereas User Settings are stored
|
||||
* globally for all possible contexts (e.g. for the whole RaceBoard independently from selected race).
|
||||
* <p>The underlying access to settings storage gets disabled if the URL contains {@code ignoreLocalSettings=true} flag.</p>
|
||||
*
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
* @see ComponentContext
|
||||
*
|
||||
* @param <S>
|
||||
* The {@link Settings} type of the settings of the root component/perspective containing all the settings
|
||||
* for itself and its subcomponents
|
||||
*
|
||||
*/
|
||||
public class ComponentContextWithSettingsStorage<S extends Settings> extends SimpleComponentContext<S> {
|
||||
|
||||
/**
|
||||
* {@code SettingsJsons} which have which have been already queried from persistence layer, or {@code null} if
|
||||
* previous settings retrievement has not been initiated.
|
||||
*/
|
||||
protected SettingsJsons cachedSettingsJsons = null;
|
||||
|
||||
/**
|
||||
* Manages the persistence layer of settings.
|
||||
*/
|
||||
protected final SettingsStorageManager<SettingsStrings> settingsStorageManager;
|
||||
|
||||
/**
|
||||
* @param rootLifecycle
|
||||
* The {@link ComponentLifecycle} of the root component/perspective
|
||||
* @param userService
|
||||
* The service which is used for server-side settings storage
|
||||
* @param storageDefinitionId
|
||||
* The definition for User Settings and Document Settings storage keys
|
||||
*/
|
||||
public ComponentContextWithSettingsStorage(ComponentLifecycle<S> rootLifecycle, UserService userService,
|
||||
StorageDefinitionId storageDefinitionId) {
|
||||
this(rootLifecycle, userService, storageDefinitionId, new SettingsSerializationHelper());
|
||||
}
|
||||
|
||||
protected ComponentContextWithSettingsStorage(ComponentLifecycle<S> rootLifecycle, UserService userService,
|
||||
StorageDefinitionId storageDefinitionId, SettingsSerializationHelper settingsSerializationHelper) {
|
||||
this(rootLifecycle, userService, storageDefinitionId, settingsSerializationHelper,
|
||||
new UserSettingsBuildingPipeline(settingsSerializationHelper));
|
||||
}
|
||||
|
||||
protected ComponentContextWithSettingsStorage(ComponentLifecycle<S> rootLifecycle, UserService userService,
|
||||
StorageDefinitionId storageDefinitionId, SettingsSerializationHelper settingsSerializationHelper,
|
||||
SettingsBuildingPipeline<SettingsJsons> settingsBuildingPipeline) {
|
||||
super(rootLifecycle, settingsSerializationHelper, settingsBuildingPipeline);
|
||||
if(IgnoreLocalSettings.getIgnoreLocalSettingsFromCurrentUrl().isIgnoreLocalSettings()) {
|
||||
this.settingsStorageManager = null;
|
||||
} else {
|
||||
this.settingsStorageManager = new UserSettingsStorageManager(userService, storageDefinitionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the initial settings and caches them for further calls of
|
||||
* {@link #getInitialSettings(OnSettingsLoadedCallback)} and
|
||||
* {@link #getInitialSettingsForComponent(Component, OnSettingsLoadedCallback)}.
|
||||
*/
|
||||
public void initialize() {
|
||||
getInitialSettings(new OnSettingsLoadedCallback<S>() {
|
||||
@Override
|
||||
public void onError(Throwable caught, S fallbackDefaultSettings) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(S settings) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets initial settings and passes these settings to the provided callback. The provided callback gets called when
|
||||
* initial/default settings are available. The callback may be called after a delay, e.g. after the settings have
|
||||
* been retrieved from a server, or immediately, e.g. when the implementation does not query information from
|
||||
* server. This method produces no side-effects if it gets called multiple times. After this method has been called
|
||||
* for the first time, subsequent calls will not produce any server round-trips or LocalStorage accesses due to its
|
||||
* internal caching.
|
||||
*
|
||||
* @param settingsReceiverCallback
|
||||
* The callback which supplies the caller with initial settings
|
||||
*/
|
||||
@Override
|
||||
public void getInitialSettings(final OnSettingsLoadedCallback<S> callback) {
|
||||
final S systemDefaultSettings = rootLifecycle.createDefaultSettings();
|
||||
if (cachedSettingsJsons == null) {
|
||||
if(settingsStorageManager != null) {
|
||||
settingsStorageManager.retrieveSettingsRepresentation(new OnSettingsLoadedCallback<SettingsStrings>() {
|
||||
|
||||
@Override
|
||||
public void onError(Throwable caught, SettingsStrings fallbackSettingsRepresentation) {
|
||||
callback.onError(caught, getSettingsObject(fallbackSettingsRepresentation, systemDefaultSettings));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(SettingsStrings settingsRepresentation) {
|
||||
callback.onSuccess(getSettingsObject(settingsRepresentation, systemDefaultSettings));
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
callback.onSuccess(getSettingsObject(new SettingsStrings(null, null), systemDefaultSettings));
|
||||
}
|
||||
|
||||
} else {
|
||||
S newDefaultSettings = settingsBuildingPipeline.getSettingsObject(systemDefaultSettings,
|
||||
cachedSettingsJsons);
|
||||
callback.onSuccess(newDefaultSettings);
|
||||
}
|
||||
}
|
||||
|
||||
private S getSettingsObject(SettingsStrings settingsRepresentation, S systemDefaultSettings) {
|
||||
cachedSettingsJsons = convertToSettingsJson(settingsRepresentation);
|
||||
S settingsObject = settingsBuildingPipeline.getSettingsObject(systemDefaultSettings,
|
||||
cachedSettingsJsons);
|
||||
return settingsObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the {@link Settings} of the provided {@link Component} are storable and whether the underlying
|
||||
* implementation enables {@link #makeSettingsDefault(Component, Settings)} calls for it.
|
||||
*
|
||||
* @param component
|
||||
* The component with potentially storable settings
|
||||
* @return {@code true} if the settings of the component are storable <b>AND</b> the {@link ComponentContext}
|
||||
* implementation has settings storage support
|
||||
*/
|
||||
@Override
|
||||
public boolean isStorageSupported(Component<?> component) {
|
||||
if (!component.hasSettings()) {
|
||||
return false;
|
||||
}
|
||||
if(settingsStorageManager == null) {
|
||||
return false;
|
||||
}
|
||||
Settings settings = component.getSettings();
|
||||
if (settings instanceof SettingsMap || settings instanceof GenericSerializableSettings) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the provided {@link Settings} of the provided {@link Component} as "User Settings" globally. Make sure to
|
||||
* call this method only when {@link #isStorageSupported(Component)} method returns {@code true}
|
||||
* for the provided {@link Component}.
|
||||
*
|
||||
* @param component
|
||||
* The component which corresponds to the provided {@link Settings}
|
||||
* @param newDefaultSettings
|
||||
* The {@link Settings} to be stored
|
||||
* @param onSettingsStoredCallback
|
||||
* The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
@Override
|
||||
public <CS extends Settings> void makeSettingsDefault(Component<CS> component, CS newDefaultSettings,
|
||||
final OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
ComponentLifecycle<CS> targetLifecycle = ComponentUtils.determineLifecycle(new ArrayList<>(component.getPath()),
|
||||
rootLifecycle);
|
||||
CS globalSettings = targetLifecycle.extractGlobalSettings(newDefaultSettings);
|
||||
updateGlobalSettings(component.getPath(), globalSettings, onSettingsStoredCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the provided {@link Settings} of the provided {@link Component} as "Document Settings" (old term "Context
|
||||
* specific Settings") for the current context. Make sure to call this method only when
|
||||
* {@link #isStorageSupported(Component)} method returns {@code true} for the provided
|
||||
* {@link Component}.
|
||||
*
|
||||
* @param component
|
||||
* The component which corresponds to the provided {@link Settings}
|
||||
* @param newSettings
|
||||
* The {@link Settings} to be stored
|
||||
* @param onSettingsStoredCallback
|
||||
* The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
@Override
|
||||
public <CS extends Settings> void storeSettingsForContext(Component<CS> component, CS newSettings,
|
||||
OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
ComponentLifecycle<CS> targetLifecycle = ComponentUtils.determineLifecycle(new ArrayList<>(component.getPath()),
|
||||
rootLifecycle);
|
||||
CS contextSpecificSettings = targetLifecycle.extractContextSpecificSettings(newSettings);
|
||||
updateContextSpecificSettings(component.getPath(), contextSpecificSettings, onSettingsStoredCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patches the settings tree with the new settings provided. The settings node with the provided path is going to be
|
||||
* created/replaced with the new settings.
|
||||
*
|
||||
* @param root
|
||||
* The root node of the settings tree
|
||||
* @param path
|
||||
* The path of the node to create/update
|
||||
* @param newSettings
|
||||
* The new settings with that the target node in the settings tree is going to be updated
|
||||
* @param pipelineLevel
|
||||
* The scope of settings used for settings storage (e.g. User Settings, or Document Settings)
|
||||
* @return The patched settings located by provided path as JSON
|
||||
*/
|
||||
private JSONObject patchJsonObject(JSONObject root, List<String> path, Settings newSettings,
|
||||
PipelineLevel pipelineLevel) {
|
||||
newSettings = cloneStorableSettings(newSettings, path);
|
||||
return patchJsonObject(root, path, Collections.unmodifiableList(new ArrayList<>(path)), newSettings,
|
||||
pipelineLevel);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <CS extends Settings> CS cloneStorableSettings(CS settingsToClone, List<String> path) {
|
||||
CS clonedSettings = ComponentUtils.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(path),
|
||||
rootLifecycle.createDefaultSettings());
|
||||
if (clonedSettings instanceof GenericSerializableSettings) {
|
||||
GenericSerializableSettings newSettings = (GenericSerializableSettings) clonedSettings;
|
||||
GenericSerializableSettings originalSettings = (GenericSerializableSettings) settingsToClone;
|
||||
SettingsDefaultValuesUtils.keepDefaults(originalSettings, newSettings);
|
||||
SettingsMergeUtils.setValues(originalSettings, newSettings);
|
||||
clonedSettings = (CS) newSettings;
|
||||
}
|
||||
// TODO maybe add support for SettingsMap? Currently, SettingsMap is never provided as parameter to this method
|
||||
return clonedSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper method for {@link #patchJsonObject(JSONObject, List, Settings, PipelineLevel)}
|
||||
*
|
||||
* @param root
|
||||
* @param path
|
||||
* @param originalPath
|
||||
* @param newSettings
|
||||
* @param pipelineLevel
|
||||
* @return
|
||||
*/
|
||||
private JSONObject patchJsonObject(JSONObject root, List<String> path, List<String> originalPath,
|
||||
Settings newSettings, PipelineLevel pipelineLevel) {
|
||||
if (path.isEmpty()) {
|
||||
return (JSONObject) settingsBuildingPipeline.getJsonObject(newSettings, pipelineLevel, originalPath);
|
||||
}
|
||||
if (root == null) {
|
||||
root = new JSONObject();
|
||||
}
|
||||
String current = path.remove(path.size() - 1);
|
||||
// we need to go further
|
||||
if (!path.isEmpty()) {
|
||||
JSONValue child = root.get(current);
|
||||
boolean haskey = root.containsKey(current);
|
||||
if (child == null || child.isObject() == null) {
|
||||
if (haskey) {
|
||||
GWT.log("Warning: replacing some subtree element that is wrong type!");
|
||||
}
|
||||
child = new JSONObject();
|
||||
root.put(current, child);
|
||||
}
|
||||
return patchJsonObject(child.isObject(), path, originalPath, newSettings, pipelineLevel);
|
||||
} else {
|
||||
JSONValue json = settingsBuildingPipeline.getJsonObject(newSettings, pipelineLevel, originalPath);
|
||||
root.put(current, json);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the User Settings' tree with the new settings provided. The settings node with the provided path is going
|
||||
* to be created/replaced with the new settings. This method may produce a server round-trip if the user is logged
|
||||
* in.
|
||||
*
|
||||
* @param path
|
||||
* The path of the settings' node to create/update
|
||||
* @param globalSettings
|
||||
* User Settings which corresponds to the provided path
|
||||
* @param onSettingsStoredCallback
|
||||
* The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
private void updateGlobalSettings(final ArrayList<String> path, final Settings globalSettings,
|
||||
final OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
settingsStorageManager.retrieveSettingsRepresentation(new OnSettingsLoadedCallback<SettingsStrings>() {
|
||||
|
||||
@Override
|
||||
public void onError(Throwable caught, SettingsStrings fallbackDefaultSettings) {
|
||||
onSettingsStoredCallback.onError(caught);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(SettingsStrings settingsRepresentation) {
|
||||
SettingsJsons result = convertToSettingsJson(settingsRepresentation);
|
||||
final JSONObject patchedGlobalSettings = patchJsonObject(result.getGlobalSettingsJson(),
|
||||
new ArrayList<>(path), globalSettings, PipelineLevel.GLOBAL_DEFAULTS);
|
||||
settingsRepresentation = convertToSettingsStrings(new SettingsJsons(patchedGlobalSettings, null));
|
||||
cachedSettingsJsons = new SettingsJsons(patchedGlobalSettings, cachedSettingsJsons.getContextSpecificSettingsJson());
|
||||
settingsStorageManager.storeSettingsRepresentation(settingsRepresentation, onSettingsStoredCallback);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the Document Settings' tree with the new settings provided. The settings node with the provided path is
|
||||
* going to be created/replaced with the new settings. This method may produce a server round-trip if the user is
|
||||
* logged in.
|
||||
*
|
||||
* @param path
|
||||
* The path of the settings' node to create/update
|
||||
* @param contextSpecificSettings
|
||||
* Document Settings which corresponds to the provided path
|
||||
* @param onSettingsStoredCallback
|
||||
* The callback which is called when the settings storage process finishes
|
||||
*/
|
||||
private void updateContextSpecificSettings(final ArrayList<String> path, final Settings contextSpecificSettings,
|
||||
final OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
settingsStorageManager.retrieveSettingsRepresentation(new OnSettingsLoadedCallback<SettingsStrings>() {
|
||||
|
||||
@Override
|
||||
public void onError(Throwable caught, SettingsStrings fallbackDefaultSettings) {
|
||||
onSettingsStoredCallback.onError(caught);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(SettingsStrings settingsRepresentation) {
|
||||
SettingsJsons result = convertToSettingsJson(settingsRepresentation);
|
||||
final JSONObject patchedContextSpecificSettings = patchJsonObject(
|
||||
result.getContextSpecificSettingsJson(), new ArrayList<>(path), contextSpecificSettings,
|
||||
PipelineLevel.CONTEXT_SPECIFIC_DEFAULTS);
|
||||
settingsRepresentation = convertToSettingsStrings(
|
||||
new SettingsJsons(null, patchedContextSpecificSettings));
|
||||
cachedSettingsJsons = new SettingsJsons(cachedSettingsJsons.getGlobalSettingsJson(), patchedContextSpecificSettings);
|
||||
settingsStorageManager.storeSettingsRepresentation(settingsRepresentation, onSettingsStoredCallback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
if(settingsStorageManager != null) {
|
||||
settingsStorageManager.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public SettingsJsons convertToSettingsJson(SettingsStrings settingsStrings) {
|
||||
JSONObject globalSettingsJson = settingsSerializationHelper
|
||||
.convertStringToJson(settingsStrings.getGlobalSettingsString());
|
||||
JSONObject contextSpecificSettingsJson = settingsSerializationHelper
|
||||
.convertStringToJson(settingsStrings.getContextSpecificSettingsString());
|
||||
return new SettingsJsons(globalSettingsJson, contextSpecificSettingsJson);
|
||||
}
|
||||
|
||||
public SettingsStrings convertToSettingsStrings(SettingsJsons settingsJsons) {
|
||||
String globalSettingsString = settingsSerializationHelper
|
||||
.convertJsonToString(settingsJsons.getGlobalSettingsJson());
|
||||
String contextSpecificSettingsString = settingsSerializationHelper
|
||||
.convertJsonToString(settingsJsons.getContextSpecificSettingsJson());
|
||||
return new SettingsStrings(globalSettingsString, contextSpecificSettingsString);
|
||||
}
|
||||
|
||||
}
|
||||
+18
-14
@@ -3,8 +3,9 @@ package com.sap.sse.security.ui.settings;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContextWithSettingsStorage;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsSerializationHelper;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
/**
|
||||
* Adds settings patching functionality to {@link ComponentContextWithSettingsStorage} implementation.
|
||||
@@ -26,20 +27,24 @@ import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
*/
|
||||
public class ComponentContextWithSettingsStorageAndPatching<S extends Settings> extends ComponentContextWithSettingsStorage<S> {
|
||||
|
||||
/**
|
||||
* Manages the persistence layer of settings.
|
||||
*/
|
||||
protected final UserSettingsStorageManagerWithPatching<S> settingsStorageManager;
|
||||
|
||||
/**
|
||||
* @param rootLifecycle
|
||||
* The {@link ComponentLifecycle} of the root component/perspective
|
||||
* @param settingsStorageManager
|
||||
* The {@link UserSettingsStorageManagerWithPatching} to be used to access stored settings and to store new settings
|
||||
* @param userService
|
||||
* The service which is used for server-side settings storage
|
||||
* @param storageDefinitionId
|
||||
* The definition for User Settings and Document Settings storage keys
|
||||
*/
|
||||
public ComponentContextWithSettingsStorageAndPatching(ComponentLifecycle<S> rootLifecycle, UserSettingsStorageManagerWithPatching<S> settingsStorageManager) {
|
||||
super(rootLifecycle, settingsStorageManager);
|
||||
this.settingsStorageManager = (UserSettingsStorageManagerWithPatching<S>) super.settingsStorageManager;
|
||||
public ComponentContextWithSettingsStorageAndPatching(ComponentLifecycle<S> rootLifecycle, UserService userService, StorageDefinitionId storageDefinitionId) {
|
||||
this(rootLifecycle, userService, storageDefinitionId, new SettingsSerializationHelper());
|
||||
}
|
||||
|
||||
protected ComponentContextWithSettingsStorageAndPatching(ComponentLifecycle<S> rootLifecycle, UserService userService, StorageDefinitionId storageDefinitionId, SettingsSerializationHelper settingsSerializationHelper) {
|
||||
this(rootLifecycle, userService, storageDefinitionId, settingsSerializationHelper, new UserSettingsBuildingPipelineWithPatching(settingsSerializationHelper));
|
||||
}
|
||||
|
||||
protected ComponentContextWithSettingsStorageAndPatching(ComponentLifecycle<S> rootLifecycle, UserService userService, StorageDefinitionId storageDefinitionId, SettingsSerializationHelper settingsSerializationHelper, UserSettingsBuildingPipelineWithPatching settingsBuildingPipeline) {
|
||||
super(rootLifecycle, userService, storageDefinitionId, settingsSerializationHelper, settingsBuildingPipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +55,7 @@ public class ComponentContextWithSettingsStorageAndPatching<S extends Settings>
|
||||
* @param settingsPatch The settings patch to apply on settings
|
||||
*/
|
||||
public<CS extends Settings> void addPatchForStoringSettings(Component<CS> component, PipelineLevel pipelineLevel, SettingsPatch<CS> settingsPatch) {
|
||||
settingsStorageManager.addPatchForStoringSettings(component, pipelineLevel, settingsPatch);
|
||||
((UserSettingsBuildingPipelineWithPatching) settingsBuildingPipeline).addPatchForStoringSettings(component, pipelineLevel, settingsPatch);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,8 +66,7 @@ public class ComponentContextWithSettingsStorageAndPatching<S extends Settings>
|
||||
* @param settingsPatch The settings patch to apply on settings
|
||||
*/
|
||||
public<CS extends Settings> void addPatchForLoadingSettings(Component<CS> component, PipelineLevel pipelineLevel, SettingsPatch<CS> settingsPatch) {
|
||||
invalidateCachedSettings();
|
||||
settingsStorageManager.addPatchForLoadingSettings(component, pipelineLevel, settingsPatch);
|
||||
((UserSettingsBuildingPipelineWithPatching) settingsBuildingPipeline).addPatchForLoadingSettings(component, pipelineLevel, settingsPatch);
|
||||
}
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.sap.sse.security.ui.settings;
|
||||
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.common.settings.generic.GenericSerializableSettings;
|
||||
import com.sap.sse.common.settings.generic.SettingsMap;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsBuildingPipeline;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsSerializationHelper;
|
||||
import com.sap.sse.gwt.settings.SettingsToStringSerializer;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
/**
|
||||
* Specialization of {@link ComponentContextWithSettingsStorage} which reimplements URL deserialization. This implementation
|
||||
* handles URL deserialization in such a way, that only the provided {@code serializedSettings} {@code String} is
|
||||
* considered as URL, and not the URL in the browser.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @see ComponentContextWithSettingsStorage
|
||||
*
|
||||
*/
|
||||
public class PlaceBasedComponentContextWithSettingsStorage<S extends Settings> extends ComponentContextWithSettingsStorage<S> {
|
||||
|
||||
/**
|
||||
* Constructs a special case of {@link ComponentContextWithSettingsStorage} which considers the provided {@code serializedSettings} as
|
||||
* URL parameters for deserialization of URL Settings.
|
||||
*
|
||||
* @param rootLifecycle
|
||||
* The {@link ComponentLifecycle} of the root component/perspective
|
||||
* @param userService
|
||||
* The service which is used for server-side settings storage
|
||||
* @param storageDefinitionId
|
||||
* The definition for User Settings and Document Settings storage keys
|
||||
* @param serializedSettings
|
||||
* Contains URL parameters for serialization of URL Settings
|
||||
*/
|
||||
public PlaceBasedComponentContextWithSettingsStorage(ComponentLifecycle<S> rootLifecycle, UserService userService,
|
||||
StorageDefinitionId storageDefinitionId, final String serializedSettings) {
|
||||
this(rootLifecycle, userService, storageDefinitionId, new SettingsSerializationHelper() {
|
||||
|
||||
private final SettingsToStringSerializer settingsToStringSerializer = new SettingsToStringSerializer();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <CS extends Settings> CS deserializeFromCurrentUrl(CS defaultSettings) {
|
||||
final CS result;
|
||||
if (defaultSettings instanceof SettingsMap) {
|
||||
result = (CS) settingsToStringSerializer.fromString(serializedSettings,
|
||||
(SettingsMap) defaultSettings);
|
||||
} else if (defaultSettings instanceof GenericSerializableSettings) {
|
||||
result = (CS) settingsToStringSerializer.fromString(serializedSettings,
|
||||
(GenericSerializableSettings) defaultSettings);
|
||||
} else {
|
||||
result = defaultSettings;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected PlaceBasedComponentContextWithSettingsStorage(ComponentLifecycle<S> rootLifecycle, UserService userService,
|
||||
StorageDefinitionId storageDefinitionId, SettingsSerializationHelper settingsSerializationHelper) {
|
||||
this(rootLifecycle, userService, storageDefinitionId, settingsSerializationHelper,
|
||||
new UserSettingsBuildingPipeline(settingsSerializationHelper));
|
||||
}
|
||||
|
||||
protected PlaceBasedComponentContextWithSettingsStorage(ComponentLifecycle<S> rootLifecycle, UserService userService,
|
||||
StorageDefinitionId storageDefinitionId, SettingsSerializationHelper settingsSerializationHelper,
|
||||
SettingsBuildingPipeline<SettingsJsons> settingsBuildingPipeline) {
|
||||
super(rootLifecycle, userService, storageDefinitionId, settingsSerializationHelper, settingsBuildingPipeline);
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package com.sap.sse.security.ui.settings;
|
||||
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.common.settings.generic.GenericSerializableSettings;
|
||||
import com.sap.sse.common.settings.generic.SettingsMap;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStringConverter;
|
||||
import com.sap.sse.gwt.settings.SettingsToStringSerializer;
|
||||
|
||||
/**
|
||||
* Specialization of {@link UserSettingsBuildingPipeline} which reimplements URL deserialization.
|
||||
* This implementation handles URL deserialization in such a way, that only the provided
|
||||
* {@code serializedSettings} {@code String} is considered as URL, and not the URL in the browser.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @see UserSettingsBuildingPipeline
|
||||
*
|
||||
*/
|
||||
public class PlaceBasedUserSettingsBuildingPipeline extends UserSettingsBuildingPipeline {
|
||||
|
||||
/**
|
||||
* Constructs an instance with a custom conversion helper which considers the provided {@code serializedSettings}
|
||||
* as URL parameters for deserialization of URL Settings.
|
||||
*
|
||||
* @param serializedSettings
|
||||
*/
|
||||
public PlaceBasedUserSettingsBuildingPipeline(final String serializedSettings) {
|
||||
super(new SettingsStringConverter() {
|
||||
|
||||
private final SettingsToStringSerializer settingsToStringSerializer = new SettingsToStringSerializer();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <S extends Settings> S deserializeFromCurrentUrl(S defaultSettings) {
|
||||
final S result;
|
||||
if (defaultSettings instanceof SettingsMap) {
|
||||
result = (S) settingsToStringSerializer.fromString(serializedSettings, (SettingsMap) defaultSettings);
|
||||
} else if (defaultSettings instanceof GenericSerializableSettings) {
|
||||
result = (S) settingsToStringSerializer.fromString(serializedSettings,
|
||||
(GenericSerializableSettings) defaultSettings);
|
||||
} else {
|
||||
result = defaultSettings;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
package com.sap.sse.security.ui.settings;
|
||||
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
/**
|
||||
* Specialization of {@link UserSettingsStorageManager} which uses {@link PlaceBasedUserSettingsBuildingPipeline} for settings construction.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @param <S>
|
||||
* The {@link Settings} type of the settings of the root component/perspective containing all the settings
|
||||
* for itself and its subcomponents
|
||||
*/
|
||||
public class PlaceBasedUserSettingsStorageManager<S extends Settings> extends UserSettingsStorageManager<S> {
|
||||
|
||||
public PlaceBasedUserSettingsStorageManager(UserService userService, StorageDefinitionId storageDefinitionId, String serializedSettings) {
|
||||
super(userService, storageDefinitionId, new PlaceBasedUserSettingsBuildingPipeline(serializedSettings));
|
||||
}
|
||||
|
||||
}
|
||||
+47
-12
@@ -1,16 +1,22 @@
|
||||
package com.sap.sse.gwt.client.shared.settings;
|
||||
package com.sap.sse.security.ui.settings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentContext;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentUtils;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsStoredCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsBuildingPipeline;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsSerializationHelper;
|
||||
|
||||
/**
|
||||
* Manages all default settings of perspectives and components. This simple implementation has no support for settings
|
||||
* storage. It is only capable of creating new default settings by means of {@link ComponentLifecycle#createDefaultSettings()} of the root
|
||||
* component managed by this {@link ComponentContext}. All in all, it is a dummy implementation for components which does
|
||||
* not have support for settings storage. If you need settings to be stored, consider
|
||||
* component managed by this {@link ComponentContext}, considering the URL parameters. If you need settings to be stored, consider
|
||||
* {@link ComponentContextWithSettingsStorage}.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
@@ -20,6 +26,13 @@ import com.sap.sse.gwt.client.shared.components.ComponentLifecycle;
|
||||
* for itself and its subcomponents
|
||||
*/
|
||||
public class SimpleComponentContext<S extends Settings> implements ComponentContext<S> {
|
||||
|
||||
protected final SettingsSerializationHelper settingsSerializationHelper;
|
||||
|
||||
/**
|
||||
* The pipeline used for the settings construction.
|
||||
*/
|
||||
protected final SettingsBuildingPipeline<SettingsJsons> settingsBuildingPipeline;
|
||||
|
||||
/**
|
||||
* The {@link ComponentLifecycle} of the root component/perspective
|
||||
@@ -32,7 +45,17 @@ public class SimpleComponentContext<S extends Settings> implements ComponentCont
|
||||
* The {@link ComponentLifecycle} of the root component/perspective
|
||||
*/
|
||||
public SimpleComponentContext(ComponentLifecycle<S> rootLifecycle) {
|
||||
this(rootLifecycle, new SettingsSerializationHelper());
|
||||
}
|
||||
|
||||
protected SimpleComponentContext(ComponentLifecycle<S> rootLifecycle, SettingsSerializationHelper settingsSerializationHelper) {
|
||||
this(rootLifecycle, settingsSerializationHelper, new UrlSettingsBuildingPipeline(settingsSerializationHelper));
|
||||
}
|
||||
|
||||
protected SimpleComponentContext(ComponentLifecycle<S> rootLifecycle, SettingsSerializationHelper settingsSerializationHelper, SettingsBuildingPipeline<SettingsJsons> settingsBuildingPipeline) {
|
||||
this.rootLifecycle = rootLifecycle;
|
||||
this.settingsSerializationHelper = settingsSerializationHelper;
|
||||
this.settingsBuildingPipeline = settingsBuildingPipeline;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,15 +93,16 @@ public class SimpleComponentContext<S extends Settings> implements ComponentCont
|
||||
*
|
||||
* @return The {@link Settings} of the root component
|
||||
*/
|
||||
public S getDefaultSettings() {
|
||||
return rootLifecycle.createDefaultSettings();
|
||||
private S getDefaultSettings() {
|
||||
S defaultSettings = rootLifecycle.createDefaultSettings();
|
||||
return settingsBuildingPipeline.getSettingsObject(defaultSettings, new SettingsJsons(null, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns always {@code false}, because it does not offer functionality for settings storage.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasMakeCustomDefaultSettingsSupport(Component<?> component) {
|
||||
public boolean isStorageSupported(Component<?> component) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -101,14 +125,25 @@ public class SimpleComponentContext<S extends Settings> implements ComponentCont
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the "System Default" {@link Settings} of the provided component and passes them to the provided callback.
|
||||
*
|
||||
* @see #getDefaultSettings()
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <CS extends Settings> void getInitialSettingsForComponent(final Component<CS> component, final OnSettingsLoadedCallback<CS> callback) {
|
||||
ComponentLifecycle<CS> componentLifecycle = ComponentUtils.determineLifecycle(new ArrayList<>(component.getPath()), rootLifecycle);
|
||||
callback.onSuccess(componentLifecycle.createDefaultSettings());
|
||||
}
|
||||
OnSettingsLoadedCallback<S> internalCallback = new OnSettingsLoadedCallback<S>() {
|
||||
|
||||
@Override
|
||||
public void onError(Throwable caught, S fallbackDefaultSettings) {
|
||||
CS componentFallbackSettings = ComponentUtils.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(component.getPath()), fallbackDefaultSettings);
|
||||
callback.onError(caught, componentFallbackSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(S settings) {
|
||||
CS componentSettings = ComponentUtils.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(component.getPath()), settings);
|
||||
callback.onSuccess(componentSettings);
|
||||
}
|
||||
};
|
||||
getInitialSettings(internalCallback);
|
||||
}
|
||||
|
||||
}
|
||||
-92
@@ -1,92 +0,0 @@
|
||||
package com.sap.sse.security.ui.settings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsStoredCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
|
||||
/**
|
||||
* This {@link SettingsStorageManager} implementation only reads settings from the URL and does not support settings storage.
|
||||
*
|
||||
* @param <S>
|
||||
* The {@link Settings} type of the settings of the root component/perspective containing all the settings
|
||||
* for itself and its subcomponents
|
||||
* @see SettingsStorageManager
|
||||
*/
|
||||
public class SimpleSettingsStorageManager<S extends Settings> implements SettingsStorageManager<S> {
|
||||
|
||||
/**
|
||||
* The pipeline used for the settings construction.
|
||||
*/
|
||||
protected final UrlSettingsBuildingPipeline settingsBuildingPipeline;
|
||||
|
||||
/**
|
||||
* Constructs the instance with a {@link UrlSettingsBuildingPipeline}.
|
||||
*/
|
||||
public SimpleSettingsStorageManager() {
|
||||
settingsBuildingPipeline = new UrlSettingsBuildingPipeline();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsStore() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void retrieveDefaultSettings(S defaultSettings, final OnSettingsLoadedCallback<S> asyncCallback) {
|
||||
asyncCallback.onSuccess(settingsBuildingPipeline.getSettingsObject(defaultSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void storeGlobalSettingsJson(JSONObject globalSettingsJson, OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
throw new UnsupportedOperationException("Settings storage is unsupported by SimpleSettingsStorageManager");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void storeContextSpecificSettingsJson(JSONObject contextSpecificSettingsJson,
|
||||
OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
throw new UnsupportedOperationException("Settings storage is unsupported by SimpleSettingsStorageManager");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public JSONValue settingsToJSON(Settings newSettings, PipelineLevel pipelineLevel, List<String> path) {
|
||||
throw new UnsupportedOperationException("Settings storage is unsupported by SimpleSettingsStorageManager");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void retrieveSettingsJsons(AsyncCallback<SettingsJsons> asyncCallback) {
|
||||
throw new UnsupportedOperationException("Settings storage is unsupported by SimpleSettingsStorageManager");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
+36
-17
@@ -4,41 +4,60 @@ import java.util.List;
|
||||
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.gwt.client.shared.settings.AbstractSettingsBuildingPipeline;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsBuildingPipeline;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsSerializationHelper;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
|
||||
/**
|
||||
* Settings building pipeline which is only capable of reading settings from URL.
|
||||
* Conversion to JSON is not supported. This implementation is supposed to be used by {@link SettingsStorageManager}
|
||||
* which offers read-only functionality for settings, and thus, does not provide persistence support.
|
||||
* Settings building pipeline which is only capable of reading settings from URL. Conversion to JSON is not supported.
|
||||
* This implementation is supposed to be used by {@link SettingsStorageManager} which offers read-only functionality for
|
||||
* settings, and thus, does not provide persistence support.
|
||||
*
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
*/
|
||||
public class UrlSettingsBuildingPipeline extends AbstractSettingsBuildingPipeline {
|
||||
|
||||
public class UrlSettingsBuildingPipeline implements SettingsBuildingPipeline<SettingsJsons> {
|
||||
|
||||
/**
|
||||
* Constructs a settings object by means of provided defaultSettings and current URL.
|
||||
*
|
||||
* @param defaultSettings The basic settings to be used
|
||||
* @param settingsJsons The persisted representation of User Settings and Document Settings, which is ignored by this implementation
|
||||
* @return The constructed settings object
|
||||
* Conversion helper which is used by this instance for type conversion/serialization between settings objects and
|
||||
* JSON Strings.
|
||||
*/
|
||||
@Override
|
||||
public <S extends Settings> S getSettingsObject(S defaultSettings, SettingsJsons settingsJsons) {
|
||||
return settingsStringConverter.deserializeFromCurrentUrl(defaultSettings);
|
||||
protected final SettingsSerializationHelper settingsSerializationHelper;
|
||||
|
||||
/**
|
||||
* Constructs an instance with a custom conversion helper between settings objects and its JSON representation.
|
||||
*
|
||||
* @param settingsSerializationHelper
|
||||
* The custom conversion helper
|
||||
*/
|
||||
public UrlSettingsBuildingPipeline(SettingsSerializationHelper settingsSerializationHelper) {
|
||||
this.settingsSerializationHelper = settingsSerializationHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation does not provide support for JSON conversion of settings objects, because it is supposed to be used
|
||||
* by read-only {@link SettingsStorageManager} implementations.
|
||||
* Constructs a settings object by means of provided defaultSettings and current URL.
|
||||
*
|
||||
* @param defaultSettings
|
||||
* The basic settings to be used
|
||||
* @param settingsRepresentation
|
||||
* The persisted representation of Settings, which is ignored by this implementation
|
||||
* @return The constructed settings object
|
||||
*/
|
||||
@Override
|
||||
public <S extends Settings> S getSettingsObject(S defaultSettings, SettingsJsons settingsRepresentation) {
|
||||
return settingsSerializationHelper.deserializeFromCurrentUrl(defaultSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation does not provide support for JSON conversion of settings objects, because it is supposed to
|
||||
* be used by read-only {@link SettingsStorageManager} implementations.
|
||||
*/
|
||||
@Override
|
||||
public JSONValue getJsonObject(Settings settings, PipelineLevel pipelineLevel, List<String> path) {
|
||||
throw new UnsupportedOperationException("This pipeline does not support JSON conversion");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+47
-39
@@ -4,72 +4,80 @@ import java.util.List;
|
||||
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.gwt.client.shared.settings.AbstractSettingsBuildingPipeline;
|
||||
import com.sap.sse.gwt.client.shared.perspective.IgnoreLocalSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStringConverter;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsSerializationHelper;
|
||||
|
||||
/**
|
||||
* Settings building pipeline which is capable of building settings considering
|
||||
* System Default Settings, persisted representations of
|
||||
* User Settings and Document Settings, and current URL.
|
||||
* The precedence of settings is:
|
||||
* Settings building pipeline which is capable of building settings considering System Default Settings, persisted
|
||||
* representations of User Settings and Document Settings, and current URL. The precedence of settings is:
|
||||
* <ul>
|
||||
* <li>System Default Settings</li>
|
||||
* <li>User Settings</li>
|
||||
* <li>Document Settings</li>
|
||||
* <li>URL Settings</li>
|
||||
* <li>System Default Settings</li>
|
||||
* <li>User Settings</li>
|
||||
* <li>Document Settings</li>
|
||||
* <li>URL Settings</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
*/
|
||||
public class UserSettingsBuildingPipeline extends AbstractSettingsBuildingPipeline {
|
||||
|
||||
public class UserSettingsBuildingPipeline extends UrlSettingsBuildingPipeline {
|
||||
|
||||
/**
|
||||
* Constructs an instance with a custom conversion helper between
|
||||
* settings objects and its JSON representation.
|
||||
* Constructs an instance with a custom conversion helper between settings objects and its JSON representation.
|
||||
*
|
||||
* @param settingsSerializationHelper
|
||||
* The custom conversion helper
|
||||
*/
|
||||
protected UserSettingsBuildingPipeline(SettingsStringConverter settingsStringConverter) {
|
||||
public UserSettingsBuildingPipeline(SettingsSerializationHelper settingsStringConverter) {
|
||||
super(settingsStringConverter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an instance with {@link SettingsStringConverter} as conversion helper between
|
||||
* settings objects and its JSON representation.
|
||||
*/
|
||||
public UserSettingsBuildingPipeline() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a settings object by means of provided defaultSettings, persisted representations of
|
||||
* User Settings and Document Settings, and current URL.
|
||||
* Constructs a settings object by means of provided defaultSettings, persisted representations of User Settings and
|
||||
* Document Settings, and current URL.
|
||||
*
|
||||
* @param defaultSettings The basic settings to be used
|
||||
* @param settingsJsons The persisted representation of User Settings and Document Settings
|
||||
* @param defaultSettings
|
||||
* The basic settings to be used
|
||||
* @param settingsJsons
|
||||
* The persisted representation of User Settings and Document Settings
|
||||
* @return The constructed settings object
|
||||
*/
|
||||
public<S extends Settings> S getSettingsObject(S defaultSettings, SettingsJsons settingsJsons) {
|
||||
if(settingsJsons.getContextSpecificSettingsJson() != null) {
|
||||
defaultSettings = settingsStringConverter.deserializeFromJson(defaultSettings, settingsJsons.getContextSpecificSettingsJson());
|
||||
} else if(settingsJsons.getGlobalSettingsJson() != null) {
|
||||
defaultSettings = settingsStringConverter.deserializeFromJson(defaultSettings, settingsJsons.getGlobalSettingsJson());
|
||||
@Override
|
||||
public <CS extends Settings> CS getSettingsObject(CS defaultSettings, SettingsJsons settingsJsons) {
|
||||
if (!isIgnoreLocalSettingsUrlFlagPresent()) {
|
||||
if (settingsJsons.getContextSpecificSettingsJson() != null) {
|
||||
defaultSettings = settingsSerializationHelper.deserializeFromJson(defaultSettings,
|
||||
settingsJsons.getContextSpecificSettingsJson());
|
||||
} else if (settingsJsons.getGlobalSettingsJson() != null) {
|
||||
defaultSettings = settingsSerializationHelper.deserializeFromJson(defaultSettings,
|
||||
settingsJsons.getGlobalSettingsJson());
|
||||
}
|
||||
}
|
||||
defaultSettings = settingsStringConverter.deserializeFromCurrentUrl(defaultSettings);
|
||||
defaultSettings = settingsSerializationHelper.deserializeFromCurrentUrl(defaultSettings);
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the provided settings object into a JSON representation without considering provided pipeline level and settings tree path.
|
||||
* Converts the provided settings object into a JSON representation without considering provided pipeline level and
|
||||
* settings tree path.
|
||||
*
|
||||
* @param settings The settings to convert to JSON representation
|
||||
* @param pipelineLevel The pipeline level which indicates the storage scope, e.g. User Settings or Document Settings.
|
||||
* @param path The path of the settings in the settings tree
|
||||
* @param settings
|
||||
* The settings to convert to JSON representation
|
||||
* @param pipelineLevel
|
||||
* The pipeline level which indicates the storage scope, e.g. User Settings or Document Settings.
|
||||
* @param path
|
||||
* The path of the settings in the settings tree
|
||||
* @return The JSON representation of the provided settings
|
||||
*/
|
||||
@Override
|
||||
public JSONValue getJsonObject(Settings newSettings, PipelineLevel pipelineLevel, List<String> path) {
|
||||
return settingsStringConverter.serializeFromSettingsObject(newSettings);
|
||||
return settingsSerializationHelper.serializeFromSettingsObject(newSettings);
|
||||
}
|
||||
|
||||
|
||||
public boolean isIgnoreLocalSettingsUrlFlagPresent() {
|
||||
return settingsSerializationHelper.deserializeFromCurrentUrl(new IgnoreLocalSettings()).isIgnoreLocalSettings();
|
||||
}
|
||||
|
||||
}
|
||||
+96
-60
@@ -13,78 +13,100 @@ import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.settings.ComponentUtils;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsSerializationHelper;
|
||||
|
||||
/**
|
||||
* Specialization of {@link UserSettingsBuildingPipeline} which offers multiple hooks for settings patching
|
||||
* throughout the pipeline. These hooks may be used to patch the settings at different pipeline levels during its construction.
|
||||
* This implementation provides additional methods for attachment of {@link SettingsPatch}s.
|
||||
* After each {@link PipelineLevel} a custom {@link SettingsPatch}
|
||||
* may be applied. The patch may partially or completely modify the resulting settings object in order to provide
|
||||
* the desired behavior of default settings for a dynamic environment, e.g. RaceBoard which determines its default settings regarding
|
||||
* to RaceModes, PlayModes and etc.
|
||||
* Specialization of {@link UserSettingsBuildingPipeline} which offers multiple hooks for settings patching throughout
|
||||
* the pipeline. These hooks may be used to patch the settings at different pipeline levels during its construction.
|
||||
* This implementation provides additional methods for attachment of {@link SettingsPatch}s. After each
|
||||
* {@link PipelineLevel} a custom {@link SettingsPatch} may be applied. The patch may partially or completely modify the
|
||||
* resulting settings object in order to provide the desired behavior of default settings for a dynamic environment,
|
||||
* e.g. RaceBoard which determines its default settings regarding to RaceModes, PlayModes and etc.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
*/
|
||||
public class UserSettingsBuildingPipelineWithPatching extends UserSettingsBuildingPipeline {
|
||||
|
||||
|
||||
private SettingsPatches patchesForStoringSettings = new SettingsPatches();
|
||||
private SettingsPatches patchesForLoadingSettings = new SettingsPatches();
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a settings object by means of provided defaultSettings, persisted representations of
|
||||
* User Settings and Document Settings, current URL, and loading patches, which have been added to this
|
||||
* pipeline instance.
|
||||
* Constructs an instance with a custom conversion helper between settings objects and its JSON representation.
|
||||
*
|
||||
* @param defaultSettings The basic settings to be used
|
||||
* @param settingsJsons The persisted representation of User Settings and Document Settings
|
||||
* @param settingsSerializationHelper
|
||||
* The custom conversion helper
|
||||
*/
|
||||
public UserSettingsBuildingPipelineWithPatching(SettingsSerializationHelper settingsStringConverter) {
|
||||
super(settingsStringConverter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a settings object by means of provided defaultSettings, persisted representations of User Settings and
|
||||
* Document Settings, current URL, and loading patches, which have been added to this pipeline instance.
|
||||
*
|
||||
* @param defaultSettings
|
||||
* The basic settings to be used
|
||||
* @param settingsJsons
|
||||
* The persisted representation of User Settings and Document Settings
|
||||
* @return The constructed settings object
|
||||
*/
|
||||
@Override
|
||||
public <CS extends Settings> CS getSettingsObject(CS defaultSettings, SettingsJsons settingsJsons) {
|
||||
boolean ignoreLocalSettings = isIgnoreLocalSettingsUrlFlagPresent();
|
||||
|
||||
defaultSettings = applyPatchesForPipelineLevel(defaultSettings, PipelineLevel.SYSTEM_DEFAULTS);
|
||||
if(settingsJsons.getContextSpecificSettingsJson() != null) {
|
||||
if (!ignoreLocalSettings && settingsJsons.getContextSpecificSettingsJson() != null) {
|
||||
defaultSettings = applyPatchesForPipelineLevel(defaultSettings, PipelineLevel.GLOBAL_DEFAULTS);
|
||||
defaultSettings = settingsStringConverter.deserializeFromJson(defaultSettings, settingsJsons.getContextSpecificSettingsJson());
|
||||
} else if(settingsJsons.getGlobalSettingsJson() != null) {
|
||||
defaultSettings = settingsStringConverter.deserializeFromJson(defaultSettings, settingsJsons.getGlobalSettingsJson());
|
||||
defaultSettings = settingsSerializationHelper.deserializeFromJson(defaultSettings,
|
||||
settingsJsons.getContextSpecificSettingsJson());
|
||||
} else if (!ignoreLocalSettings && settingsJsons.getGlobalSettingsJson() != null) {
|
||||
defaultSettings = settingsSerializationHelper.deserializeFromJson(defaultSettings,
|
||||
settingsJsons.getGlobalSettingsJson());
|
||||
defaultSettings = applyPatchesForPipelineLevel(defaultSettings, PipelineLevel.GLOBAL_DEFAULTS);
|
||||
} else {
|
||||
defaultSettings = applyPatchesForPipelineLevel(defaultSettings, PipelineLevel.GLOBAL_DEFAULTS);
|
||||
}
|
||||
defaultSettings = applyPatchesForPipelineLevel(defaultSettings, PipelineLevel.CONTEXT_SPECIFIC_DEFAULTS);
|
||||
defaultSettings = settingsStringConverter.deserializeFromCurrentUrl(defaultSettings);
|
||||
defaultSettings = settingsSerializationHelper.deserializeFromCurrentUrl(defaultSettings);
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
private <CS extends Settings> CS applyPatchesForPipelineLevel(CS defaultSettings, PipelineLevel pipelineLevel) {
|
||||
for (Entry<List<String>, List<SettingsPatch<? extends Settings>>> entry : patchesForLoadingSettings.getSettingsPatches(pipelineLevel).entrySet()) {
|
||||
for (Entry<List<String>, List<SettingsPatch<? extends Settings>>> entry : patchesForLoadingSettings
|
||||
.getSettingsPatches(pipelineLevel).entrySet()) {
|
||||
List<String> path = entry.getKey();
|
||||
List<SettingsPatch<? extends Settings>> settingsPatches = entry.getValue();
|
||||
if(!settingsPatches.isEmpty()) {
|
||||
Settings patchedComponentSettings = ComponentUtils.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(path), defaultSettings);
|
||||
if (!settingsPatches.isEmpty()) {
|
||||
Settings patchedComponentSettings = ComponentUtils
|
||||
.determineComponentSettingsFromPerspectiveSettings(new ArrayList<>(path), defaultSettings);
|
||||
for (SettingsPatch<? extends Settings> settingsPatch : settingsPatches) {
|
||||
patchedComponentSettings = patchSettings(patchedComponentSettings, settingsPatch);
|
||||
}
|
||||
defaultSettings = ComponentUtils.patchSettingsTree(new ArrayList<>(path), patchedComponentSettings, defaultSettings);
|
||||
defaultSettings = ComponentUtils.patchSettingsTree(new ArrayList<>(path), patchedComponentSettings,
|
||||
defaultSettings);
|
||||
}
|
||||
}
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the provided settings object into a JSON representation considering storing patches,
|
||||
* which have been added to this pipeline instance.
|
||||
* Converts the provided settings object into a JSON representation considering storing patches, which have been
|
||||
* added to this pipeline instance.
|
||||
*
|
||||
* @param settings The settings to convert to JSON representation
|
||||
* @param pipelineLevel The pipeline level which indicates the storage scope, e.g. User Settings or Document Settings.
|
||||
* @param path The path of the settings in the settings tree
|
||||
* @param settings
|
||||
* The settings to convert to JSON representation
|
||||
* @param pipelineLevel
|
||||
* The pipeline level which indicates the storage scope, e.g. User Settings or Document Settings.
|
||||
* @param path
|
||||
* The path of the settings in the settings tree
|
||||
* @return The JSON representation of the provided settings
|
||||
*/
|
||||
@Override
|
||||
public JSONValue getJsonObject(Settings settings, PipelineLevel pipelineLevel, List<String> path) {
|
||||
for (PipelineLevel level : pipelineLevel.getSortedLevelsUntilCurrent()) {
|
||||
List<SettingsPatch<? extends Settings>> settingsPatches = patchesForStoringSettings.getSettingsPatches(path, level);
|
||||
List<SettingsPatch<? extends Settings>> settingsPatches = patchesForStoringSettings.getSettingsPatches(path,
|
||||
level);
|
||||
for (SettingsPatch<? extends Settings> settingsPatch : settingsPatches) {
|
||||
settings = patchSettings(settings, settingsPatch);
|
||||
}
|
||||
@@ -93,76 +115,90 @@ public class UserSettingsBuildingPipelineWithPatching extends UserSettingsBuildi
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private<CS extends Settings> CS patchSettings(Settings settings, SettingsPatch<CS> settingsPatch) {
|
||||
private <CS extends Settings> CS patchSettings(Settings settings, SettingsPatch<CS> settingsPatch) {
|
||||
return settingsPatch.patchSettings((CS) settings);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a settings patch for transforming settings before storing them.
|
||||
*
|
||||
* @param component The component which the targeted settings for patching belong to
|
||||
* @param pipelineLevel The pipeline level <b>AFTER</b> that the patch should be applied on settings
|
||||
* @param settingsPatch The settings patch to apply on settings
|
||||
* @param component
|
||||
* The component which the targeted settings for patching belong to
|
||||
* @param pipelineLevel
|
||||
* The pipeline level <b>AFTER</b> that the patch should be applied on settings
|
||||
* @param settingsPatch
|
||||
* The settings patch to apply on settings
|
||||
*/
|
||||
public<CS extends Settings> void addPatchForStoringSettings(Component<CS> component, PipelineLevel pipelineLevel, SettingsPatch<CS> settingsPatch) {
|
||||
public <CS extends Settings> void addPatchForStoringSettings(Component<CS> component, PipelineLevel pipelineLevel,
|
||||
SettingsPatch<CS> settingsPatch) {
|
||||
patchesForStoringSettings.addSettingsPatch(component.getPath(), settingsPatch, pipelineLevel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a settings patch for settings object construction.
|
||||
*
|
||||
* @param component The component which the targeted settings for patching belong to
|
||||
* @param pipelineLevel The pipeline level <b>AFTER</b> that the patch should be applied on settings
|
||||
* @param settingsPatch The settings patch to apply on settings
|
||||
* @param component
|
||||
* The component which the targeted settings for patching belong to
|
||||
* @param pipelineLevel
|
||||
* The pipeline level <b>AFTER</b> that the patch should be applied on settings
|
||||
* @param settingsPatch
|
||||
* The settings patch to apply on settings
|
||||
*/
|
||||
public<CS extends Settings> void addPatchForLoadingSettings(Component<CS> component, PipelineLevel pipelineLevel, SettingsPatch<CS> settingsPatch) {
|
||||
public <CS extends Settings> void addPatchForLoadingSettings(Component<CS> component, PipelineLevel pipelineLevel,
|
||||
SettingsPatch<CS> settingsPatch) {
|
||||
patchesForLoadingSettings.addSettingsPatch(component.getPath(), settingsPatch, pipelineLevel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal helper class for management of provided settings patches in relation to its pipeline levels
|
||||
* and components that provided patches belong to.
|
||||
* Internal helper class for management of provided settings patches in relation to its pipeline levels and
|
||||
* components that provided patches belong to.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
*/
|
||||
private static class SettingsPatches {
|
||||
|
||||
|
||||
private Map<PipelineLevel, Map<List<String>, List<SettingsPatch<? extends Settings>>>> patchesForSettings = new HashMap<>();
|
||||
|
||||
public void addSettingsPatch(List<String> path, SettingsPatch<? extends Settings> settingsPatch, PipelineLevel pipelineLevel) {
|
||||
Map<List<String>, List<SettingsPatch<? extends Settings>>> pipelinePatches = patchesForSettings.get(pipelineLevel);
|
||||
if(pipelinePatches == null) {
|
||||
|
||||
public void addSettingsPatch(List<String> path, SettingsPatch<? extends Settings> settingsPatch,
|
||||
PipelineLevel pipelineLevel) {
|
||||
Map<List<String>, List<SettingsPatch<? extends Settings>>> pipelinePatches = patchesForSettings
|
||||
.get(pipelineLevel);
|
||||
if (pipelinePatches == null) {
|
||||
pipelinePatches = new HashMap<>();
|
||||
patchesForSettings.put(pipelineLevel, pipelinePatches);
|
||||
}
|
||||
List<SettingsPatch<? extends Settings>> componentPatches = pipelinePatches.get(path);
|
||||
if(componentPatches == null) {
|
||||
if (componentPatches == null) {
|
||||
componentPatches = new ArrayList<>();
|
||||
pipelinePatches.put(path, componentPatches);
|
||||
}
|
||||
componentPatches.add(settingsPatch);
|
||||
}
|
||||
|
||||
public List<SettingsPatch<? extends Settings>> getSettingsPatches(List<String> path, PipelineLevel pipelineLevel) {
|
||||
Map<List<String>, List<SettingsPatch<? extends Settings>>> pipelinePatches = patchesForSettings.get(pipelineLevel);
|
||||
if(pipelinePatches == null) {
|
||||
|
||||
public List<SettingsPatch<? extends Settings>> getSettingsPatches(List<String> path,
|
||||
PipelineLevel pipelineLevel) {
|
||||
Map<List<String>, List<SettingsPatch<? extends Settings>>> pipelinePatches = patchesForSettings
|
||||
.get(pipelineLevel);
|
||||
if (pipelinePatches == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<SettingsPatch<? extends Settings>> componentPatches = pipelinePatches.get(path);
|
||||
if(componentPatches == null) {
|
||||
if (componentPatches == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return componentPatches;
|
||||
}
|
||||
|
||||
public Map<List<String>, List<SettingsPatch<? extends Settings>>> getSettingsPatches(PipelineLevel pipelineLevel) {
|
||||
Map<List<String>, List<SettingsPatch<? extends Settings>>> pipelinePatches = patchesForSettings.get(pipelineLevel);
|
||||
if(pipelinePatches == null) {
|
||||
|
||||
public Map<List<String>, List<SettingsPatch<? extends Settings>>> getSettingsPatches(
|
||||
PipelineLevel pipelineLevel) {
|
||||
Map<List<String>, List<SettingsPatch<? extends Settings>>> pipelinePatches = patchesForSettings
|
||||
.get(pipelineLevel);
|
||||
if (pipelinePatches == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return pipelinePatches;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+57
-167
@@ -7,20 +7,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
import com.google.gwt.storage.client.Storage;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.gwt.client.shared.perspective.IgnoreLocalSettings;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsLoadedCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.OnSettingsStoredCallback;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsBuildingPipeline;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsJsons;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStorageManager;
|
||||
import com.sap.sse.gwt.client.shared.settings.SettingsStrings;
|
||||
import com.sap.sse.gwt.settings.SettingsToUrlSerializer;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.client.UserStatusEventHandler;
|
||||
import com.sap.sse.security.ui.shared.UserDTO;
|
||||
@@ -31,23 +23,10 @@ import com.sap.sse.security.ui.shared.UserDTO;
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @param <S>
|
||||
* The {@link Settings} type of the settings of the root component/perspective containing all the settings
|
||||
* for itself and its subcomponents
|
||||
* @see SettingsStorageManager
|
||||
*/
|
||||
public class UserSettingsStorageManager<S extends Settings> implements SettingsStorageManager<S> {
|
||||
public class UserSettingsStorageManager implements SettingsStorageManager<SettingsStrings> {
|
||||
|
||||
/**
|
||||
* {@code SettingsJsons} which have which have been already queried from persistence layer, or {@code null} if previous settings retrievement has not been initiated.
|
||||
*/
|
||||
protected SettingsJsons cachedSettingsJsons = null;
|
||||
|
||||
/**
|
||||
* The pipeline used for the settings construction.
|
||||
*/
|
||||
protected final SettingsBuildingPipeline settingsBuildingPipeline;
|
||||
|
||||
/**
|
||||
* The key which is associated with the User Settings. Different keys will cause multiple/different settings
|
||||
* instances to be stored in the storage.
|
||||
@@ -78,109 +57,76 @@ public class UserSettingsStorageManager<S extends Settings> implements SettingsS
|
||||
/**
|
||||
* Callbacks which are waiting to be called when persistent settings representation has loaded.
|
||||
*/
|
||||
private Queue<AsyncCallback<SettingsJsons>> retrieveSettingsCallbacksQueue = new LinkedList<>();
|
||||
private Queue<OnSettingsLoadedCallback<SettingsStrings>> retrieveSettingsCallbacksQueue = new LinkedList<>();
|
||||
|
||||
/**
|
||||
* Constructs the instance with a custom {@link SettingsBuildingPipeline}.
|
||||
*
|
||||
* @param userService The service which is used for server-side settings storage
|
||||
* @param storageDefinitionId The definition for User Settings and Document Settings storage keys
|
||||
* @param settingsBuildingPipeline The custom pipeline to be used for settings construction
|
||||
*/
|
||||
protected UserSettingsStorageManager(UserService userService, StorageDefinitionId storageDefinitionId, SettingsBuildingPipeline settingsBuildingPipeline) {
|
||||
this.settingsBuildingPipeline = settingsBuildingPipeline;
|
||||
public UserSettingsStorageManager(UserService userService, StorageDefinitionId storageDefinitionId) {
|
||||
this.userService = userService;
|
||||
this.storageGlobalKey = storageDefinitionId.generateStorageGlobalKey();
|
||||
this.storageContextSpecificKey = storageDefinitionId.generateStorageContextSpecificKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the instance with {@link UserSettingsBuildingPipeline}.
|
||||
*
|
||||
* @param userService The service which is used for server-side settings storage
|
||||
* @param storageDefinitionId The definition for User Settings and Document Settings storage keys
|
||||
*/
|
||||
public UserSettingsStorageManager(UserService userService, StorageDefinitionId storageDefinitionId) {
|
||||
this(userService, storageDefinitionId, new UserSettingsBuildingPipeline());
|
||||
@Override
|
||||
public void storeSettingsRepresentation(SettingsStrings settingsStrings, OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
storeSettingsStringsOnLocalStorage(settingsStrings);
|
||||
if (userService.getCurrentUser() != null) {
|
||||
storeSettingsStringsOnServer(settingsStrings, onSettingsStoredCallback);
|
||||
} else {
|
||||
onSettingsStoredCallback.onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsStore() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void storeSettingsStringsOnLocalStorage(SettingsStrings settingsStrings, boolean storeGlobalSettings, boolean storeContextSpecificSettings) {
|
||||
private void storeSettingsStringsOnLocalStorage(SettingsStrings settingsStrings) {
|
||||
Storage localStorage = Storage.getLocalStorageIfSupported();
|
||||
if (localStorage != null) {
|
||||
if(storeGlobalSettings) {
|
||||
if(settingsStrings.getGlobalSettingsString() != null) {
|
||||
localStorage.removeItem(storageGlobalKey);
|
||||
if(settingsStrings.getGlobalSettingsString() != null) {
|
||||
localStorage.setItem(storageGlobalKey, settingsStrings.getGlobalSettingsString());
|
||||
}
|
||||
localStorage.setItem(storageGlobalKey, settingsStrings.getGlobalSettingsString());
|
||||
}
|
||||
if(storeContextSpecificSettings) {
|
||||
if(settingsStrings.getContextSpecificSettingsString() != null) {
|
||||
localStorage.removeItem(storageContextSpecificKey);
|
||||
if(settingsStrings.getContextSpecificSettingsString() != null) {
|
||||
localStorage.setItem(storageContextSpecificKey, settingsStrings.getContextSpecificSettingsString());
|
||||
}
|
||||
localStorage.setItem(storageContextSpecificKey, settingsStrings.getContextSpecificSettingsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void storeSettingsStringsOnServer(SettingsStrings settingsStrings, final OnSettingsStoredCallback onSettingsStoredCallback, boolean storeGlobalSettings, boolean storeContextSpecificSettings) {
|
||||
Map<String, String> keyValuePairs = new HashMap<>();
|
||||
if(storeGlobalSettings) {
|
||||
keyValuePairs.put(storageGlobalKey, settingsStrings.getGlobalSettingsString());
|
||||
}
|
||||
if(storeContextSpecificSettings) {
|
||||
keyValuePairs.put(storageContextSpecificKey, settingsStrings.getContextSpecificSettingsString());
|
||||
}
|
||||
userService.setPreferences(keyValuePairs, new AsyncCallback<Void>() {
|
||||
|
||||
private void storeSettingsStringsOnServer(SettingsStrings settingsStrings, final OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
AsyncCallback<Void> asyncCallback = new AsyncCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
onSettingsStoredCallback.onError(caught);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
onSettingsStoredCallback.onSuccess();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if(settingsStrings.getContextSpecificSettingsString() == null || settingsStrings.getGlobalSettingsString() == null) {
|
||||
if(settingsStrings.getContextSpecificSettingsString() != null) {
|
||||
userService.setPreference(storageContextSpecificKey, settingsStrings.getContextSpecificSettingsString(), asyncCallback);
|
||||
}
|
||||
if(settingsStrings.getGlobalSettingsString() != null) {
|
||||
userService.setPreference(storageGlobalKey, settingsStrings.getGlobalSettingsString(), asyncCallback);
|
||||
}
|
||||
} else {
|
||||
Map<String, String> keyValuePairs = new HashMap<>();
|
||||
if(settingsStrings.getGlobalSettingsString() != null) {
|
||||
keyValuePairs.put(storageGlobalKey, settingsStrings.getGlobalSettingsString());
|
||||
}
|
||||
if(settingsStrings.getContextSpecificSettingsString() != null) {
|
||||
keyValuePairs.put(storageContextSpecificKey, settingsStrings.getContextSpecificSettingsString());
|
||||
}
|
||||
userService.setPreferences(keyValuePairs, asyncCallback);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void retrieveDefaultSettings(final S defaultSettings, final OnSettingsLoadedCallback<S> callback) {
|
||||
if(cachedSettingsJsons == null) {
|
||||
retrieveSettingsJsons(new AsyncCallback<SettingsJsons>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
SettingsStrings localStorageSettings = retrieveSettingsStringsFromLocalStorage();
|
||||
S newDefaultSettings = settingsBuildingPipeline.getSettingsObject(defaultSettings, localStorageSettings);
|
||||
cachedSettingsJsons = settingsBuildingPipeline.getSettingsStringConverter().convertToSettingsJson(localStorageSettings);
|
||||
callback.onError(caught, newDefaultSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(SettingsJsons settingsJsons) {
|
||||
S newDefaultSettings = settingsBuildingPipeline.getSettingsObject(defaultSettings, settingsJsons);
|
||||
cachedSettingsJsons = settingsJsons;
|
||||
callback.onSuccess(newDefaultSettings);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
S newDefaultSettings = settingsBuildingPipeline.getSettingsObject(defaultSettings, cachedSettingsJsons);
|
||||
callback.onSuccess(newDefaultSettings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -220,55 +166,13 @@ public class UserSettingsStorageManager<S extends Settings> implements SettingsS
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public JSONValue settingsToJSON(Settings newSettings, PipelineLevel pipelineLevel, List<String> path) {
|
||||
return settingsBuildingPipeline.getJsonObject(newSettings, pipelineLevel, path);
|
||||
}
|
||||
|
||||
private void storeSettingsJsons(SettingsJsons settingsJsons, OnSettingsStoredCallback onSettingsStoredCallback, boolean storeGlobalSettings, boolean storeContextSpecificSettings) {
|
||||
invalidateCache();
|
||||
SettingsStrings settingsStrings = settingsBuildingPipeline.getSettingsStringConverter().convertToSettingsStrings(settingsJsons);
|
||||
storeSettingsStringsOnLocalStorage(settingsStrings, storeGlobalSettings, storeContextSpecificSettings);
|
||||
if (userService.getCurrentUser() != null) {
|
||||
storeSettingsStringsOnServer(settingsStrings, onSettingsStoredCallback, storeGlobalSettings, storeContextSpecificSettings);
|
||||
} else {
|
||||
onSettingsStoredCallback.onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
cachedSettingsJsons = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void storeGlobalSettingsJson(JSONObject globalSettingsJson,
|
||||
OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
SettingsJsons settingsJsons = new SettingsJsons(globalSettingsJson, null);
|
||||
storeSettingsJsons(settingsJsons, onSettingsStoredCallback, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void storeContextSpecificSettingsJson(JSONObject contextSpecificSettingsJson,
|
||||
OnSettingsStoredCallback onSettingsStoredCallback) {
|
||||
SettingsJsons settingsJsons = new SettingsJsons(null, contextSpecificSettingsJson);
|
||||
storeSettingsJsons(settingsJsons, onSettingsStoredCallback, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void retrieveSettingsJsons(AsyncCallback<SettingsJsons> asyncCallback) {
|
||||
retrieveSettingsCallbacksQueue.add(asyncCallback);
|
||||
public void retrieveSettingsRepresentation(OnSettingsLoadedCallback<SettingsStrings> callback) {
|
||||
retrieveSettingsCallbacksQueue.add(callback);
|
||||
if(userStatusEventHandler == null) {
|
||||
this.userStatusEventHandler = new UserStatusEventHandler() {
|
||||
|
||||
@@ -277,22 +181,22 @@ public class UserSettingsStorageManager<S extends Settings> implements SettingsS
|
||||
//call this method always on user status change event in order to cause sync between local storage and server
|
||||
if(!initialUserSetting) {
|
||||
initialUserSetting = true;
|
||||
requestSettingsJsons();
|
||||
retrieveSettingsStringsFromServerOrLocalStorage();
|
||||
}
|
||||
}
|
||||
};
|
||||
userService.addUserStatusEventHandler(userStatusEventHandler, true);
|
||||
} else if(initialUserSetting) {
|
||||
requestSettingsJsons();
|
||||
retrieveSettingsStringsFromServerOrLocalStorage();
|
||||
}
|
||||
}
|
||||
|
||||
private void requestSettingsJsons() {
|
||||
private void retrieveSettingsStringsFromServerOrLocalStorage() {
|
||||
if (userService.getCurrentUser() == null) {
|
||||
SettingsStrings settingsStrings = retrieveSettingsStringsFromLocalStorage();
|
||||
AsyncCallback<SettingsJsons> asyncCallback;
|
||||
while((asyncCallback = retrieveSettingsCallbacksQueue.poll()) != null) {
|
||||
asyncCallback.onSuccess(settingsBuildingPipeline.getSettingsStringConverter().convertToSettingsJson(settingsStrings));
|
||||
OnSettingsLoadedCallback<SettingsStrings> callback;
|
||||
while((callback = retrieveSettingsCallbacksQueue.poll()) != null) {
|
||||
callback.onSuccess(settingsStrings);
|
||||
}
|
||||
} else {
|
||||
retrieveSettingsStringsFromServer(new AsyncCallback<SettingsStrings>() {
|
||||
@@ -300,17 +204,18 @@ public class UserSettingsStorageManager<S extends Settings> implements SettingsS
|
||||
@Override
|
||||
public void onSuccess(SettingsStrings serverSettingsStrings) {
|
||||
serverSettingsStrings = syncLocalStorageAndServer(serverSettingsStrings);
|
||||
AsyncCallback<SettingsJsons> asyncCallback;
|
||||
while((asyncCallback = retrieveSettingsCallbacksQueue.poll()) != null) {
|
||||
asyncCallback.onSuccess(settingsBuildingPipeline.getSettingsStringConverter().convertToSettingsJson(serverSettingsStrings));
|
||||
OnSettingsLoadedCallback<SettingsStrings> callback;
|
||||
while((callback = retrieveSettingsCallbacksQueue.poll()) != null) {
|
||||
callback.onSuccess(serverSettingsStrings);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
AsyncCallback<SettingsJsons> asyncCallback;
|
||||
while((asyncCallback = retrieveSettingsCallbacksQueue.poll()) != null) {
|
||||
asyncCallback.onFailure(caught);
|
||||
SettingsStrings fallbackSettingsStrings = retrieveSettingsStringsFromLocalStorage();
|
||||
OnSettingsLoadedCallback<SettingsStrings> callback;
|
||||
while((callback = retrieveSettingsCallbacksQueue.poll()) != null) {
|
||||
callback.onError(caught, fallbackSettingsStrings);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -332,28 +237,13 @@ public class UserSettingsStorageManager<S extends Settings> implements SettingsS
|
||||
public void onError(Throwable caught) {
|
||||
//nothing to do
|
||||
}
|
||||
}, true, true);
|
||||
});
|
||||
}
|
||||
serverSettingsStrings = localStorageSettingsStrings;
|
||||
} else {
|
||||
storeSettingsStringsOnLocalStorage(serverSettingsStrings, true, true);
|
||||
storeSettingsStringsOnLocalStorage(serverSettingsStrings);
|
||||
}
|
||||
return serverSettingsStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SettingsStorageManager} instance based on the ignoreLocalSettings URL flag. if
|
||||
* ignoreLocalSettings is set to <code>true</code>, a SimpleSettingsStorageManager is created. A
|
||||
* UserSettingsStorageManager is created otherwise.
|
||||
*/
|
||||
public static <S extends Settings> SettingsStorageManager<S> createSettingsStorageManager(UserService userService, StorageDefinitionId storageDefinitionId) {
|
||||
if (getIgnoreLocalSettings().isIgnoreLocalSettings()) {
|
||||
return new SimpleSettingsStorageManager<>();
|
||||
}
|
||||
return new UserSettingsStorageManager<>(userService, storageDefinitionId);
|
||||
}
|
||||
|
||||
public static IgnoreLocalSettings getIgnoreLocalSettings() {
|
||||
return new SettingsToUrlSerializer().deserializeFromCurrentLocation(new IgnoreLocalSettings());
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
package com.sap.sse.security.ui.settings;
|
||||
|
||||
import com.sap.sse.common.settings.Settings;
|
||||
import com.sap.sse.gwt.client.shared.components.Component;
|
||||
import com.sap.sse.gwt.client.shared.settings.PipelineLevel;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
/**
|
||||
* Specialization of {@link UserSettingsStorageManager} which uses {@link UserSettingsBuildingPipelineWithPatching} for settings construction.
|
||||
* This implementation provides additional methods for attachment of {@link SettingsPatch}s. There are multiple hooks in
|
||||
* the underlying {@link UserSettingsBuildingPipelineWithPatching} which can be used to influence the
|
||||
* settings construction in its construction pipeline. After each {@link PipelineLevel} a custom {@link SettingsPatch}
|
||||
* may be applied. The patch may partially or completely modify the resulting settings object in order to provide
|
||||
* the desired behavior of default settings for a dynamic environment, e.g. RaceBoard which determines its default settings regarding
|
||||
* to RaceModes, PlayModes and etc.
|
||||
*
|
||||
* @author Vladislav Chumak
|
||||
*
|
||||
* @param <S>
|
||||
* The {@link Settings} type of the settings of the root component/perspective containing all the settings
|
||||
* for itself and its subcomponents
|
||||
*/
|
||||
public class UserSettingsStorageManagerWithPatching<S extends Settings> extends UserSettingsStorageManager<S> {
|
||||
|
||||
/**
|
||||
* The typed pipeline used for the settings construction.
|
||||
*/
|
||||
protected final UserSettingsBuildingPipelineWithPatching settingsBuildingPipeline;
|
||||
|
||||
/**
|
||||
* Constructs the instance with {@link UserSettingsBuildingPipelineWithPatching}.
|
||||
*
|
||||
* @param userService The service which is used for server-side settings storage
|
||||
* @param storageDefinitionId The definition for User Settings and Document Settings storage keys
|
||||
*/
|
||||
public UserSettingsStorageManagerWithPatching(UserService userService, StorageDefinitionId storageDefinitionId) {
|
||||
super(userService, storageDefinitionId, new UserSettingsBuildingPipelineWithPatching());
|
||||
settingsBuildingPipeline = (UserSettingsBuildingPipelineWithPatching) super.settingsBuildingPipeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a settings patch for transforming settings before storing them.
|
||||
*
|
||||
* @param component The component which the targeted settings for patching belong to
|
||||
* @param pipelineLevel The pipeline level <b>AFTER</b> that the patch should be applied on settings
|
||||
* @param settingsPatch The settings patch to apply on settings
|
||||
*/
|
||||
public<CS extends Settings> void addPatchForStoringSettings(Component<CS> component, PipelineLevel pipelineLevel, SettingsPatch<CS> settingsPatch) {
|
||||
settingsBuildingPipeline.addPatchForStoringSettings(component, pipelineLevel, settingsPatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a settings patch for settings object construction.
|
||||
*
|
||||
* @param component The component which the targeted settings for patching belong to
|
||||
* @param pipelineLevel The pipeline level <b>AFTER</b> that the patch should be applied on settings
|
||||
* @param settingsPatch The settings patch to apply on settings
|
||||
*/
|
||||
public<CS extends Settings> void addPatchForLoadingSettings(Component<CS> component, PipelineLevel pipelineLevel, SettingsPatch<CS> settingsPatch) {
|
||||
settingsBuildingPipeline.addPatchForLoadingSettings(component, pipelineLevel, settingsPatch);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user