From ec56c95dbac30399daf2e20d3b8b3375c2ae19fa Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sat, 7 Oct 2017 00:10:17 +0200 Subject: [PATCH] compilable but untested version that captures the dimension reduction Change-Id: Id48f8b09018aec881ee19ed3d05a52ffc1f8f846 --- ...edDimensionsDTO_CustomFieldSerializer.java | 67 +++++++++++++++++ .../gwt/ui/datamining/DataMiningService.java | 5 +- .../ui/datamining/DataMiningServiceAsync.java | 7 +- .../datamining/FilterSelectionProvider.java | 3 + .../QueryDefinitionProviderWithControls.java | 1 + .../DimensionFilterSelectionProvider.java | 25 +++++-- ...RetrieverChainFilterSelectionProvider.java | 23 ++++-- ...RetrieverLevelFilterSelectionProvider.java | 34 ++++++++- .../gwt/ui/server/DataMiningServiceImpl.java | 31 ++++---- .../sailing/gwt/ui/LeaderboardEditing.gwt.xml | 2 +- ...TestFunctionManagerAsFunctionProvider.java | 2 +- .../sap/sse/datamining/DataMiningServer.java | 3 +- .../management/FunctionProvider.java | 3 +- .../datamining/impl/DataMiningServerImpl.java | 3 +- .../management/FunctionManager.java | 75 ++++++++++++------- 15 files changed, 215 insertions(+), 69 deletions(-) create mode 100755 java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/dto/ReducedDimensionsDTO_CustomFieldSerializer.java diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/dto/ReducedDimensionsDTO_CustomFieldSerializer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/dto/ReducedDimensionsDTO_CustomFieldSerializer.java new file mode 100755 index 00000000000..8186256134c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/dto/ReducedDimensionsDTO_CustomFieldSerializer.java @@ -0,0 +1,67 @@ +package com.google.gwt.user.client.rpc.core.com.sap.sse.datamining.shared.impl.dto; + +import java.util.HashMap; +import java.util.HashSet; + +import com.google.gwt.user.client.rpc.CustomFieldSerializer; +import com.google.gwt.user.client.rpc.SerializationException; +import com.google.gwt.user.client.rpc.SerializationStreamReader; +import com.google.gwt.user.client.rpc.SerializationStreamWriter; +import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; +import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; +import com.sap.sse.datamining.shared.impl.dto.ReducedDimensionsDTO; + +/** + * Ensures that the {@link FunctionDTO#getLocalizedName() localizedName} field is serialized by + * really evaluating it eagerly now; this way, an optional lazy evaluation function does not need + * to be serialized. + * + * @author Axel Uhl (d043530) + * + */ +public class ReducedDimensionsDTO_CustomFieldSerializer extends CustomFieldSerializer { + + @Override + public void serializeInstance(SerializationStreamWriter streamWriter, ReducedDimensionsDTO instance) + throws SerializationException { + serialize(streamWriter, instance); + } + + public static void serialize(SerializationStreamWriter streamWriter, ReducedDimensionsDTO instance) + throws SerializationException { + final HashMap> reducedDimensions = instance.getReducedDimensions(); + streamWriter.writeObject(reducedDimensions); + final HashMap fromOriginalToReducedDimension = new HashMap<>(instance.getFromOriginalToReducedDimension()); + streamWriter.writeObject(fromOriginalToReducedDimension); + } + + @Override + public boolean hasCustomInstantiateInstance() { + return true; + } + + @Override + public ReducedDimensionsDTO instantiateInstance(SerializationStreamReader streamReader) + throws SerializationException { + return instantiate(streamReader); + } + + @SuppressWarnings("unchecked") // the cast to List is the problem here + public static ReducedDimensionsDTO instantiate(SerializationStreamReader streamReader) + throws SerializationException { + final HashMap fromOriginalToReducedDimension = (HashMap) streamReader.readObject(); + final HashMap> reducedDimensions = (HashMap>) streamReader.readObject(); + return new ReducedDimensionsDTO(reducedDimensions, fromOriginalToReducedDimension); + } + + @Override + public void deserializeInstance(SerializationStreamReader streamReader, ReducedDimensionsDTO instance) + throws SerializationException { + deserialize(streamReader, instance); + } + + public static void deserialize(SerializationStreamReader streamReader, ReducedDimensionsDTO instance) { + // Done by instantiateInstance + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningService.java index 522a47f2dcd..7ce63efaa92 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningService.java @@ -17,6 +17,7 @@ import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO; import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; +import com.sap.sse.datamining.shared.impl.dto.ReducedDimensionsDTO; public interface DataMiningService extends RemoteService { @@ -28,9 +29,7 @@ public interface DataMiningService extends RemoteService { HashSet getAggregatorDefinitionsFor(FunctionDTO extractionFunction, String localeInfoName); HashSet getDimensionsFor(DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName); - HashMap> getDimensionsMappedByLevelFor( - DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName); - HashMap> getReducedDimensionsMappedByLevelFor( + ReducedDimensionsDTO getReducedDimensionsMappedByLevelFor( DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName); ArrayList getDataRetrieverChainDefinitions(String localeName); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningServiceAsync.java index 2ccd6d3a95c..e186ac4f18b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningServiceAsync.java @@ -18,6 +18,7 @@ import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO; import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; +import com.sap.sse.datamining.shared.impl.dto.ReducedDimensionsDTO; public interface DataMiningServiceAsync { @@ -31,10 +32,8 @@ public interface DataMiningServiceAsync { AsyncCallback> asyncCallback); void getDimensionsFor(DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName, AsyncCallback> callback); - void getDimensionsMappedByLevelFor(DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName, - AsyncCallback>> callback); - public void getReducedDimensionsMappedByLevelFor(DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName, - AsyncCallback>> callback); + void getReducedDimensionsMappedByLevelFor(DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, + String localeInfoName, AsyncCallback callback); void getDataRetrieverChainDefinitions(String localeInfoName, AsyncCallback> asyncCallback); void getDataRetrieverChainDefinitionsFor(FunctionDTO statisticToCalculate, String localeInfoName, diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/FilterSelectionProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/FilterSelectionProvider.java index 5666f6ab74f..c1bd4607e53 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/FilterSelectionProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/FilterSelectionProvider.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.HashSet; import com.sap.sse.common.settings.SerializableSettings; +import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO; import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; @@ -19,4 +20,6 @@ public interface FilterSelectionProvider extends DataMiningComponentProvider availableDimensions) { dimensionListBox.setAcceptableValues(availableDimensions); } @@ -240,8 +252,9 @@ class DimensionFilterSelectionProvider { void setSelectedDimensionAndValues(FunctionDTO functionDTO, Collection selection) { dimensionChangedHandler.firstChange = false; - selectionToBeApplied = selection; dimensionListBox.setValue(functionDTO, true); + selectionToBeApplied = selection; + updateSelectionTable(/* notifyListenersWhenSelectionChanged */ true); } public Widget getEntryWidget() { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/ListRetrieverChainFilterSelectionProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/ListRetrieverChainFilterSelectionProvider.java index 0eb143c1f00..6b7c701dcf0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/ListRetrieverChainFilterSelectionProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/ListRetrieverChainFilterSelectionProvider.java @@ -1,6 +1,7 @@ package com.sap.sailing.gwt.ui.datamining.selection.filter; import java.io.Serializable; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -32,10 +33,12 @@ import com.sap.sailing.gwt.ui.datamining.FilterSelectionProvider; import com.sap.sailing.gwt.ui.datamining.presentation.PlainFilterSelectionPresenter; import com.sap.sse.common.settings.SerializableSettings; import com.sap.sse.datamining.shared.DataMiningSession; +import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO; import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO; import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; +import com.sap.sse.datamining.shared.impl.dto.ReducedDimensionsDTO; import com.sap.sse.gwt.client.ErrorReporter; import com.sap.sse.gwt.client.shared.components.AbstractComponent; import com.sap.sse.gwt.client.shared.components.Component; @@ -105,6 +108,17 @@ public class ListRetrieverChainFilterSelectionProvider extends AbstractComponent mainPanel.setWidgetHidden(selectionPresenterScrollPanel, true); } + @Override + public void setHighestRetrieverLevelWithFilterDimension(FunctionDTO dimension, GroupKey groupKey) { + for (final DataRetrieverLevelDTO retrieverLevel : retrieverChain.getRetrieverLevels()) { + final RetrieverLevelFilterSelectionProvider selectionProvider = selectionProvidersMappedByRetrievedDataType.get(retrieverLevel); + if (selectionProvider.hasDimension(dimension)) { + selectionProvider.addFilter(dimension, Collections.singleton(groupKey)); + break; + } + } + } + @Override public void awaitReloadComponents() { isAwaitingReload = true; @@ -139,15 +153,16 @@ public class ListRetrieverChainFilterSelectionProvider extends AbstractComponent retrieverLevelDataProvider.getList().addAll(retrieverChain.getRetrieverLevels()); retrieverLevelList.setPageSize(retrieverLevelDataProvider.getList().size()); - dataMiningService.getReducedDimensionsMappedByLevelFor(retrieverChain, LocaleInfo.getCurrentLocale().getLocaleName(), new AsyncCallback>>() { + dataMiningService.getReducedDimensionsMappedByLevelFor(retrieverChain, LocaleInfo.getCurrentLocale().getLocaleName(), + new AsyncCallback() { @Override public void onFailure(Throwable caught) { errorReporter.reportError("Error fetching the dimensions of the retrieval chain from the server: " + caught.getMessage()); } @Override - public void onSuccess(HashMap> dimensionsMappedByLevel) { + public void onSuccess(ReducedDimensionsDTO dimensionsMappedByLevel) { int firstFilterableRetrieverLevel = Integer.MAX_VALUE; - for (Entry> dimensionsEntry : dimensionsMappedByLevel.entrySet()) { + for (Entry> dimensionsEntry : dimensionsMappedByLevel.getReducedDimensions().entrySet()) { if (!dimensionsEntry.getValue().isEmpty()) { DataRetrieverLevelDTO retrieverLevel = dimensionsEntry.getKey(); RetrieverLevelFilterSelectionProvider selectionProvider = @@ -158,12 +173,10 @@ public class ListRetrieverChainFilterSelectionProvider extends AbstractComponent retrieverChain,retrieverLevel); selectionProvider.setAvailableDimensions(dimensionsEntry.getValue()); selectionProvidersMappedByRetrievedDataType.put(retrieverLevel, selectionProvider); - firstFilterableRetrieverLevel = retrieverLevel.getLevel() < firstFilterableRetrieverLevel ? retrieverLevel.getLevel() : firstFilterableRetrieverLevel; } } - retrieverLevelSelectionModel.setSelected(retrieverChain.getRetrieverLevel(firstFilterableRetrieverLevel), true); } }); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/RetrieverLevelFilterSelectionProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/RetrieverLevelFilterSelectionProvider.java index a425467359a..2cb54399a66 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/RetrieverLevelFilterSelectionProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/selection/filter/RetrieverLevelFilterSelectionProvider.java @@ -9,11 +9,13 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import com.google.gwt.dom.client.Style.Display; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync; +import com.sap.sse.common.Util; import com.sap.sse.common.settings.AbstractSettings; import com.sap.sse.common.settings.SerializableSettings; import com.sap.sse.datamining.shared.DataMiningSession; @@ -116,7 +118,11 @@ public class RetrieverLevelFilterSelectionProvider extends AbstractComponent getSelectedDimensions() { Collection selectedDimensions = new ArrayList<>(); for (DimensionFilterSelectionProvider dimensionFilter : dimensionSelectionProviders) { @@ -174,13 +180,35 @@ public class RetrieverLevelFilterSelectionProvider extends AbstractComponent + * + * Precondition: {@link #hasDimension(FunctionDTO) hasDimension(dimension)}{@code == true} + */ + public void addFilter(FunctionDTO dimension, Set values) { + DimensionFilterSelectionProvider dimensionFilter = null; + for (final DimensionFilterSelectionProvider dimensionSelectionProvider : dimensionSelectionProviders) { + if (Util.equalsWithNull(dimensionSelectionProvider.getSelectedDimension(), dimension)) { + dimensionFilter = dimensionSelectionProvider; + break; + } + } + if (dimensionFilter == null) { + // add dimension filter and set value selection: + dimensionFilter = createDimensionSelectionProvider(); + addDimensionSelectionProvider(dimensionFilter); + updateAvailableDimensions(); + } + dimensionFilter.setSelectedDimensionAndValues(dimension, values); + } + public void applySelection(HashMap> filterSelection) { dimensionSelectionProviders.clear(); mainPanel.clear(); - List sortedDimensions = new ArrayList<>(filterSelection.keySet()); Collections.sort(sortedDimensions); - for (FunctionDTO functionDTO : sortedDimensions) { DimensionFilterSelectionProvider dimensionFilter = createDimensionSelectionProvider(); addDimensionSelectionProvider(dimensionFilter); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java index 984430d39d5..740f0e3bdd2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java @@ -34,6 +34,7 @@ import com.sap.sse.datamining.data.QueryResult; import com.sap.sse.datamining.factories.DataMiningDTOFactory; import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.impl.components.DataRetrieverLevel; +import com.sap.sse.datamining.impl.components.management.ReducedDimensions; import com.sap.sse.datamining.impl.data.QueryResultImpl; import com.sap.sse.datamining.shared.DataMiningSession; import com.sap.sse.datamining.shared.GroupKey; @@ -48,6 +49,7 @@ import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; import com.sap.sse.datamining.shared.impl.dto.ModifiableStatisticQueryDefinitionDTO; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; +import com.sap.sse.datamining.shared.impl.dto.ReducedDimensionsDTO; import com.sap.sse.i18n.ResourceBundleStringMessages; public class DataMiningServiceImpl extends RemoteServiceServlet implements DataMiningService { @@ -133,34 +135,29 @@ public class DataMiningServiceImpl extends RemoteServiceServlet implements DataM } @Override - public HashMap> getDimensionsMappedByLevelFor(DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName) { - SecurityUtils.getSubject().checkPermission(Permission.DATA_MINING.getStringPermissionForObjects(Mode.READ, dataRetrieverChainDefinitionDTO.getName())); - DataRetrieverChainDefinition dataRetrieverChainDefinition = getDataMiningServer().getDataRetrieverChainDefinitionForDTO(dataRetrieverChainDefinitionDTO); - Map, Iterable>> dimensions = getDataMiningServer() - .getDimensionsMappedByLevelFor(dataRetrieverChainDefinition); - return dimensionsMappedByLevelAsDTOs(dimensions, localeInfoName); - } - - @Override - public HashMap> getReducedDimensionsMappedByLevelFor( + public ReducedDimensionsDTO getReducedDimensionsMappedByLevelFor( DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, String localeInfoName) { SecurityUtils.getSubject().checkPermission(Permission.DATA_MINING.getStringPermissionForObjects(Mode.READ, dataRetrieverChainDefinitionDTO.getName())); DataRetrieverChainDefinition dataRetrieverChainDefinition = getDataMiningServer().getDataRetrieverChainDefinitionForDTO(dataRetrieverChainDefinitionDTO); - Map, Iterable>> reducedDimensions = getDataMiningServer() - .getReducedDimensionsMappedByLevelFor(dataRetrieverChainDefinition); - return dimensionsMappedByLevelAsDTOs(reducedDimensions, localeInfoName); + ReducedDimensions reducedDimensions = getDataMiningServer().getReducedDimensionsMappedByLevelFor(dataRetrieverChainDefinition); + return reducedDimensionsAsDTO(reducedDimensions, localeInfoName); } - private HashMap> dimensionsMappedByLevelAsDTOs( - Map, Iterable>> dimensions, String localeInfoName) { + private ReducedDimensionsDTO reducedDimensionsAsDTO( + ReducedDimensions dimensions, String localeInfoName) { HashMap> dimensionDTOs = new HashMap<>(); ResourceBundleStringMessages stringMessages = getDataMiningServer().getStringMessages(); Locale locale = ResourceBundleStringMessages.Util.getLocaleFor(localeInfoName); - for (Entry, Iterable>> dimensionsEntry : dimensions.entrySet()) { + for (final Entry, Iterable>> dimensionsEntry : dimensions.getReducedDimensions().entrySet()) { dimensionDTOs.put(dtoFactory.createDataRetrieverLevelDTO(dimensionsEntry.getKey(), stringMessages, locale), functionsAsDTOs(dimensionsEntry.getValue(), localeInfoName)); } - return dimensionDTOs; + HashMap fromOriginalToReducedDTO = new HashMap<>(); + for (final Entry, Function> fromOriginalToReduced : dimensions.getFromOriginalDimensionToReducedDimension().entrySet()) { + fromOriginalToReducedDTO.put(dtoFactory.createFunctionDTO(fromOriginalToReduced.getKey(), stringMessages, locale), + dtoFactory.createFunctionDTO(fromOriginalToReduced.getValue(), stringMessages, locale)); + } + return new ReducedDimensionsDTO(dimensionDTOs, fromOriginalToReducedDTO); } private HashSet functionsAsDTOs(Iterable> functions, String localeInfoName) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/LeaderboardEditing.gwt.xml b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/LeaderboardEditing.gwt.xml index 7619376595a..3ea9b979924 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/LeaderboardEditing.gwt.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/LeaderboardEditing.gwt.xml @@ -16,7 +16,7 @@ - + diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/functions/TestFunctionManagerAsFunctionProvider.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/functions/TestFunctionManagerAsFunctionProvider.java index 6968399cf10..5299793fbbc 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/functions/TestFunctionManagerAsFunctionProvider.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/functions/TestFunctionManagerAsFunctionProvider.java @@ -114,7 +114,7 @@ public class TestFunctionManagerAsFunctionProvider { break; } } - final Map, Iterable>> reducedDimensionsMappedByLevel = server.getReducedDimensionsMappedByLevelFor(retrieverChain); + final Map, Iterable>> reducedDimensionsMappedByLevel = server.getReducedDimensionsMappedByLevelFor(retrieverChain).getReducedDimensions(); assertThat(reducedDimensionsMappedByLevel, is(expectedDimensions)); } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/DataMiningServer.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/DataMiningServer.java index 51a4667814a..7bc335154e8 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/DataMiningServer.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/DataMiningServer.java @@ -17,6 +17,7 @@ import com.sap.sse.datamining.components.management.QueryDefinitionDTOProvider; import com.sap.sse.datamining.data.QueryResult; import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.impl.components.DataRetrieverLevel; +import com.sap.sse.datamining.impl.components.management.ReducedDimensions; import com.sap.sse.datamining.shared.DataMiningSession; import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO; import com.sap.sse.datamining.shared.impl.PredefinedQueryIdentifier; @@ -40,7 +41,7 @@ public interface DataMiningServer { Iterable> getStatisticsFor(Class sourceType); Iterable> getDimensionsFor(Class sourceType); Map, Iterable>> getDimensionsMappedByLevelFor(DataRetrieverChainDefinition dataRetrieverChainDefinition); - Map, Iterable>> getReducedDimensionsMappedByLevelFor(DataRetrieverChainDefinition dataRetrieverChainDefinition); + ReducedDimensions getReducedDimensionsMappedByLevelFor(DataRetrieverChainDefinition dataRetrieverChainDefinition); Function getFunctionForDTO(FunctionDTO functionDTO); DataRetrieverChainDefinitionProvider getDataRetrieverChainDefinitionProvider(); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/components/management/FunctionProvider.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/components/management/FunctionProvider.java index cf9b3dbfbe2..3d39b5ddba7 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/components/management/FunctionProvider.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/components/management/FunctionProvider.java @@ -6,6 +6,7 @@ import java.util.Map; import com.sap.sse.datamining.components.DataRetrieverChainDefinition; import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.impl.components.DataRetrieverLevel; +import com.sap.sse.datamining.impl.components.management.ReducedDimensions; import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; public interface FunctionProvider { @@ -19,7 +20,7 @@ public interface FunctionProvider { public Map, Iterable>> getDimensionsMappedByLevelFor( DataRetrieverChainDefinition dataRetrieverChainDefinition); - public Map, Iterable>> getReducedDimensionsMappedByLevelFor( + public ReducedDimensions getReducedDimensionsMappedByLevelFor( DataRetrieverChainDefinition dataRetrieverChainDefinition); /** diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java index 2fa1717a9f5..762b9431a67 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java @@ -38,6 +38,7 @@ import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.impl.components.DataRetrieverLevel; import com.sap.sse.datamining.impl.components.management.AbstractMemoryMonitorAction; import com.sap.sse.datamining.impl.components.management.QueryManagerMemoryMonitor; +import com.sap.sse.datamining.impl.components.management.ReducedDimensions; import com.sap.sse.datamining.impl.components.management.RuntimeMemoryInfoProvider; import com.sap.sse.datamining.impl.components.management.StrategyPerQueryTypeManager; import com.sap.sse.datamining.shared.DataMiningSession; @@ -234,7 +235,7 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer { } @Override - public Map, Iterable>> getReducedDimensionsMappedByLevelFor( + public ReducedDimensions getReducedDimensionsMappedByLevelFor( DataRetrieverChainDefinition dataRetrieverChainDefinition) { return functionRegistry.getReducedDimensionsMappedByLevelFor(dataRetrieverChainDefinition); } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/management/FunctionManager.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/management/FunctionManager.java index 37fb5b51063..25cf919bea6 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/management/FunctionManager.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/management/FunctionManager.java @@ -285,48 +285,71 @@ public class FunctionManager implements FunctionRegistry, FunctionProvider { } @Override - public Map, Iterable>> getReducedDimensionsMappedByLevelFor( + public ReducedDimensions getReducedDimensionsMappedByLevelFor( DataRetrieverChainDefinition dataRetrieverChainDefinition) { Map, Iterable>> dimensionsMappedByLevel = getDimensionsMappedByLevelFor(dataRetrieverChainDefinition); - Map, Iterable>> reducedDimensions = new HashMap<>(); List> retrieverLevels = dataRetrieverChainDefinition.getDataRetrieverLevels(); + ReducedDimensions reducedDimensions = new ReducedDimensions(); for (DataRetrieverLevel retrieverLevel : retrieverLevels) { - Iterable> dimensions = dimensionsMappedByLevel.get(retrieverLevel); + Iterable> dimensionsOfLevel = dimensionsMappedByLevel.get(retrieverLevel); DataRetrieverLevel previousRetrieverLevel = retrieverLevel.getLevel() > 0 ? retrieverLevels.get(retrieverLevel.getLevel() - 1) : null; - if (reducedDimensions.isEmpty() || previousRetrieverLevel == null) { - reducedDimensions.put(retrieverLevel, dimensions); + final ReducedDimensions reducedDimensionsForLevel; + if (previousRetrieverLevel == null) { + assert reducedDimensions.getReducedDimensions().isEmpty(); + // for the first retriever level no reduction takes place; create a ReducedDimensions object + // to "add" onto the empty ReducedDimensions object using the full set of dimensions of this level + final Map, Iterable>> currentLevelToAllItsDimensions = new HashMap<>(); + final Map, Function> fromOriginalToReducedDimension = new HashMap<>(); + currentLevelToAllItsDimensions.put(retrieverLevel, dimensionsOfLevel); + for (final Function dimension : dimensionsOfLevel) { + fromOriginalToReducedDimension.put(dimension, dimension); + } + reducedDimensionsForLevel = new ReducedDimensions(currentLevelToAllItsDimensions, fromOriginalToReducedDimension); } else { - reducedDimensions.put(retrieverLevel, reduce(dimensions, previousRetrieverLevel, dimensionsMappedByLevel.get(previousRetrieverLevel))); + reducedDimensionsForLevel = reduce(dimensionsOfLevel, previousRetrieverLevel, + dimensionsMappedByLevel.get(previousRetrieverLevel), retrieverLevel); } + reducedDimensions = reducedDimensions.createByAdd(reducedDimensionsForLevel, + /* replaceExistingMappingsFromOriginalToReducedDimension */ true); } return reducedDimensions; } - private Iterable> reduce(Iterable> dimensionsToReduce, DataRetrieverLevel previousRetrieverLevel, Iterable> previousDimensions) { + private ReducedDimensions reduce(Iterable> dimensionsToReduce, + DataRetrieverLevel previousRetrieverLevel, Iterable> previousDimensions, + DataRetrieverLevel currentRetrieverLevel) { + final Iterable> reducedDimensions; + final Map, Function> fromOriginalToReducedDimensions = new HashMap<>(); if (Util.isEmpty(previousDimensions)) { - return dimensionsToReduce; - } - - Collection> reducedDimensions = new HashSet<>(); - for (Function dimension : dimensionsToReduce) { - boolean isAllowed = true; - if (ConcatenatingCompoundFunction.class.isAssignableFrom(dimension.getClass())) { - ConcatenatingCompoundFunction compoundDimension = (ConcatenatingCompoundFunction) dimension; - List> simpleFunctions = compoundDimension.getSimpleFunctions(); - if (previousRetrieverLevel.getRetrievedDataType().isAssignableFrom(simpleFunctions.get(0).getReturnType())) { - List> subList = simpleFunctions.subList(1, compoundDimension.getSimpleFunctions().size()); - Function subFunction = subList.size() == 1 ? subList.get(0) - : functionFactory.createCompoundFunction(subList); - if (Util.contains(previousDimensions, subFunction)) { - isAllowed = false; + reducedDimensions = dimensionsToReduce; + for (final Function dimensionToReduce : dimensionsToReduce) { + fromOriginalToReducedDimensions.put(dimensionToReduce, dimensionToReduce); + } + } else { + final Set> modifiableReducedDimensions = new HashSet<>(); + reducedDimensions = modifiableReducedDimensions; + for (Function dimension : dimensionsToReduce) { + boolean isAllowed = true; + if (ConcatenatingCompoundFunction.class.isAssignableFrom(dimension.getClass())) { + ConcatenatingCompoundFunction compoundDimension = (ConcatenatingCompoundFunction) dimension; + List> simpleFunctions = compoundDimension.getSimpleFunctions(); + if (previousRetrieverLevel.getRetrievedDataType().isAssignableFrom(simpleFunctions.get(0).getReturnType())) { + List> subList = simpleFunctions.subList(1, simpleFunctions.size()); + Function subFunction = subList.size() == 1 ? subList.get(0) + : functionFactory.createCompoundFunction(subList); + if (Util.contains(previousDimensions, subFunction)) { + isAllowed = false; // TODO record the reduction process, mapping original dimension to equal element from previousDimensions + } } } - } - if (isAllowed) { - reducedDimensions.add(dimension); + if (isAllowed) { + modifiableReducedDimensions.add(dimension); + } } } - return reducedDimensions; + final Map, Iterable>> reducedDimensionsPerRetrieverLevel = new HashMap<>(); + reducedDimensionsPerRetrieverLevel.put(currentRetrieverLevel, reducedDimensions); + return new ReducedDimensions(reducedDimensionsPerRetrieverLevel, fromOriginalToReducedDimensions); } @Override