Updated the GroupingProvider of the data mining UI

This commit is contained in:
Lennart Hensler committed 2014-08-12 17:01:53 +02:00
1 parent 5cc0a2bd68
commit 5957ea2610
13 files changed
+98 -65

No files matched your search

@@ -18,7 +18,7 @@ public interface QueryDefinitionDeprecated extends Serializable {
public AggregatorType getAggregatorType();
public List<DimensionIdentifier> getDimensionsToGroupBy();
public List<FunctionDTO> getDimensionsToGroupBy();
public Map<DimensionIdentifier, Iterable<? extends Serializable>> getSelection();
@@ -21,7 +21,7 @@ public class QueryDefinitionDeprecatedImpl implements QueryDefinitionDeprecated
private GrouperType grouperType;
private AggregatorType aggregatorType;
private List<DimensionIdentifier> dimensionsToGroupBy;
private List<FunctionDTO> dimensionsToGroupBy;
private Map<DimensionIdentifier, Iterable<? extends Serializable>> selectionMappedByDimension;
/**
@@ -36,7 +36,7 @@ public class QueryDefinitionDeprecatedImpl implements QueryDefinitionDeprecated
this.extractionFunction = extractionFunction;
this.aggregatorType = aggregatorType;
dimensionsToGroupBy = new ArrayList<DimensionIdentifier>();
dimensionsToGroupBy = new ArrayList<FunctionDTO>();
selectionMappedByDimension = new HashMap<DimensionIdentifier, Iterable<? extends Serializable>>();
}
@@ -61,7 +61,7 @@ public class QueryDefinitionDeprecatedImpl implements QueryDefinitionDeprecated
}
@Override
public List<DimensionIdentifier> getDimensionsToGroupBy() {
public List<FunctionDTO> getDimensionsToGroupBy() {
return dimensionsToGroupBy;
}
@@ -70,7 +70,7 @@ public class QueryDefinitionDeprecatedImpl implements QueryDefinitionDeprecated
return selectionMappedByDimension;
}
public void appendDimensionToGroupBy(DimensionIdentifier dimension) {
public void appendDimensionToGroupBy(FunctionDTO dimension) {
dimensionsToGroupBy.add(dimension);
}
@@ -6,6 +6,7 @@ import java.util.Map.Entry;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.datamining.shared.QueryDefinitionDeprecated;
import com.sap.sse.datamining.shared.QueryDefinition;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.QueryDefinitionImpl;
public class QueryDefinitionConverter {
@@ -22,9 +23,8 @@ public class QueryDefinitionConverter {
filterSelectionEntry.getValue());
}
for (DimensionIdentifier dimensionIdentifier : queryDefinitionDeprecated.getDimensionsToGroupBy()) {
queryDefinition.appendDimensionToGroupBy(DeprecatedEnumsToFunctionDTOConverter
.getFunctionDTOFor(dimensionIdentifier));
for (FunctionDTO dimension : queryDefinitionDeprecated.getDimensionsToGroupBy()) {
queryDefinition.appendDimensionToGroupBy(dimension);
}
return queryDefinition;
@@ -3,7 +3,6 @@ package com.sap.sailing.gwt.ui.datamining;
import java.util.Collection;
import com.google.gwt.user.client.rpc.RemoteService;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.QueryDefinitionDeprecated;
import com.sap.sailing.datamining.shared.SailingDataMiningSerializationDummy;
import com.sap.sse.datamining.shared.QueryResult;
@@ -14,7 +13,7 @@ public interface DataMiningService extends RemoteService {
Collection<FunctionDTO> getAllStatistics(String localeInfoName);
Collection<FunctionDTO> getDimensionsFor(DataTypes dataType, String localeInfoName);
Collection<FunctionDTO> getDimensionsFor(FunctionDTO extractionFunction, String localeInfoName);
<ResultType extends Number> QueryResult<ResultType> runQuery(QueryDefinitionDeprecated queryDefinition) throws Exception;
@@ -3,7 +3,6 @@ package com.sap.sailing.gwt.ui.datamining;
import java.util.Collection;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.QueryDefinitionDeprecated;
import com.sap.sailing.datamining.shared.SailingDataMiningSerializationDummy;
import com.sap.sse.datamining.shared.QueryResult;
@@ -15,7 +14,7 @@ public interface DataMiningServiceAsync {
void getAllStatistics(String localeInfoName, AsyncCallback<Collection<FunctionDTO>> callback);
void getDimensionsFor(DataTypes dataType, String localeInfoName, AsyncCallback<Collection<FunctionDTO>> callback);
void getDimensionsFor(FunctionDTO extractionFunction, String localeInfoName, AsyncCallback<Collection<FunctionDTO>> callback);
<ResultType extends Number> void runQuery(QueryDefinitionDeprecated queryDefinition, AsyncCallback<QueryResult<ResultType>> callback);
@@ -2,16 +2,16 @@ package com.sap.sailing.gwt.ui.datamining;
import java.util.Collection;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.datamining.shared.QueryDefinitionDeprecated;
import com.sap.sailing.gwt.ui.client.shared.components.Component;
import com.sap.sse.datamining.shared.components.GrouperType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public interface GroupingProvider extends Component<Object> {
public GrouperType getGrouperType();
public Collection<DimensionIdentifier> getDimensionsToGroupBy();
public Collection<FunctionDTO> getDimensionsToGroupBy();
public String getCustomGrouperScriptText();
public void applyQueryDefinition(QueryDefinitionDeprecated queryDefinition);
@@ -5,7 +5,6 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.datamining.shared.QueryDefinitionDeprecated;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
@@ -14,6 +13,7 @@ import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.QueryDefinitionChangedListener;
import com.sap.sailing.gwt.ui.datamining.QueryDefinitionProvider;
import com.sap.sse.datamining.shared.components.GrouperType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public abstract class AbstractQueryDefinitionProvider implements QueryDefinitionProvider {
@@ -62,7 +62,7 @@ public abstract class AbstractQueryDefinitionProvider implements QueryDefinition
ValidateGrouper: switch (grouper) {
case Dimensions:
for (DimensionIdentifier dimension : queryDefinition.getDimensionsToGroupBy()) {
for (FunctionDTO dimension : queryDefinition.getDimensionsToGroupBy()) {
if (dimension != null) {
break ValidateGrouper;
}
@@ -1,61 +1,91 @@
package com.sap.sailing.gwt.ui.datamining.selection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ValueListBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.datamining.shared.DimensionIdentifier.OrdinalComparator;
import com.sap.sailing.datamining.shared.QueryDefinitionDeprecated;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.AbstractObjectRenderer;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
import com.sap.sailing.gwt.ui.client.shared.components.SimpleObjectRenderer;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.GroupingChangedListener;
import com.sap.sailing.gwt.ui.datamining.GroupingProvider;
import com.sap.sse.datamining.shared.components.GrouperType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public class RestrictedGroupingProvider implements GroupingProvider {
private static final OrdinalComparator dimensionComparator = new DimensionIdentifier.OrdinalComparator();
public class MultiDimensionalGroupingProvider implements GroupingProvider {
private final StringMessages stringMessages;
private final DataMiningServiceAsync dataMiningService;
private final ErrorReporter errorReporter;
private final Set<GroupingChangedListener> listeners;
private final HorizontalPanel mainPanel;
private final List<ValueListBox<DimensionIdentifier>> dimensionToGroupByBoxes;
private Collection<FunctionDTO> availableDimensions;
private final List<ValueListBox<FunctionDTO>> dimensionToGroupByBoxes;
public RestrictedGroupingProvider(StringMessages stringMessages) {
public MultiDimensionalGroupingProvider(StringMessages stringMessages, DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter) {
this.stringMessages = stringMessages;
this.dataMiningService = dataMiningService;
this.errorReporter = errorReporter;
listeners = new HashSet<GroupingChangedListener>();
dimensionToGroupByBoxes = new ArrayList<ValueListBox<DimensionIdentifier>>();
dimensionToGroupByBoxes = new ArrayList<ValueListBox<FunctionDTO>>();
mainPanel = new HorizontalPanel();
mainPanel.setSpacing(5);
mainPanel.add(new Label(this.stringMessages.groupBy() + ":"));
ValueListBox<DimensionIdentifier> firstDimensionToGroupByBox = createDimensionToGroupByBox();
addDimensionToGroupByBoxAndUpdateAcceptableValues(firstDimensionToGroupByBox);
}
private ValueListBox<DimensionIdentifier> createDimensionToGroupByBox() {
ValueListBox<DimensionIdentifier> dimensionToGroupByBox = new ValueListBox<DimensionIdentifier>(new SimpleObjectRenderer<DimensionIdentifier>());
dimensionToGroupByBox.addValueChangeHandler(new ValueChangeHandler<DimensionIdentifier>() {
public void updateAvailableDimensions(FunctionDTO forExtractionFunction) {
//Removing all list boxes
//TODO implement a smarter algorithm to handle the loss of selected dimensions
for (ValueListBox<FunctionDTO> dimensionToGroupByBox : dimensionToGroupByBoxes) {
mainPanel.remove(dimensionToGroupByBox);
}
dimensionToGroupByBoxes.clear();
dataMiningService.getDimensionsFor(forExtractionFunction, LocaleInfo.getCurrentLocale().getLocaleName(), new AsyncCallback<Collection<FunctionDTO>>() {
@Override
public void onSuccess(Collection<FunctionDTO> dimensions) {
//TODO implement a smarter algorithm to handle the loss of selected dimensions
availableDimensions = dimensions;
ValueListBox<FunctionDTO> firstDimensionToGroupByBox = createDimensionToGroupByBox();
addDimensionToGroupByBoxAndUpdateAcceptableValues(firstDimensionToGroupByBox);
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error fetching the dimensions from the server: " + caught.getMessage());
}
});
}
private ValueListBox<FunctionDTO> createDimensionToGroupByBox() {
ValueListBox<FunctionDTO> dimensionToGroupByBox = new ValueListBox<FunctionDTO>(new AbstractObjectRenderer<FunctionDTO>() {
@Override
protected String convertObjectToString(FunctionDTO function) {
return function.getDisplayName();
}
});
dimensionToGroupByBox.addValueChangeHandler(new ValueChangeHandler<FunctionDTO>() {
private boolean firstChange = true;
@Override
public void onValueChange(ValueChangeEvent<DimensionIdentifier> event) {
public void onValueChange(ValueChangeEvent<FunctionDTO> event) {
if (firstChange && event.getValue() != null) {
ValueListBox<DimensionIdentifier> newDimensionToGroupByBox = createDimensionToGroupByBox();
ValueListBox<FunctionDTO> newDimensionToGroupByBox = createDimensionToGroupByBox();
addDimensionToGroupByBox(newDimensionToGroupByBox);
firstChange = false;
} else if (event.getValue() == null) {
@@ -70,24 +100,23 @@ public class RestrictedGroupingProvider implements GroupingProvider {
return dimensionToGroupByBox;
}
private void addDimensionToGroupByBoxAndUpdateAcceptableValues(ValueListBox<DimensionIdentifier> dimensionToGroupByBox) {
private void addDimensionToGroupByBoxAndUpdateAcceptableValues(ValueListBox<FunctionDTO> dimensionToGroupByBox) {
addDimensionToGroupByBox(dimensionToGroupByBox);
updateAcceptableValues();
}
private void addDimensionToGroupByBox(ValueListBox<DimensionIdentifier> dimensionToGroupByBox) {
private void addDimensionToGroupByBox(ValueListBox<FunctionDTO> dimensionToGroupByBox) {
mainPanel.add(dimensionToGroupByBox);
dimensionToGroupByBoxes.add(dimensionToGroupByBox);
}
private void updateAcceptableValues() {
for (ValueListBox<DimensionIdentifier> dimensionToGroupByBox : dimensionToGroupByBoxes) {
List<DimensionIdentifier> acceptableValues = new ArrayList<DimensionIdentifier>(Arrays.asList(DimensionIdentifier.values()));
for (ValueListBox<FunctionDTO> dimensionToGroupByBox : dimensionToGroupByBoxes) {
List<FunctionDTO> acceptableValues = new ArrayList<FunctionDTO>(availableDimensions);
acceptableValues.removeAll(getDimensionsToGroupBy());
if (dimensionToGroupByBox.getValue() != null) {
acceptableValues.add(dimensionToGroupByBox.getValue());
}
Collections.sort(acceptableValues, dimensionComparator);
acceptableValues.add(null);
dimensionToGroupByBox.setAcceptableValues(acceptableValues);
}
@@ -99,9 +128,9 @@ public class RestrictedGroupingProvider implements GroupingProvider {
}
@Override
public Collection<DimensionIdentifier> getDimensionsToGroupBy() {
Collection<DimensionIdentifier> dimensionsToGroupBy = new ArrayList<DimensionIdentifier>();
for (ValueListBox<DimensionIdentifier> dimensionListBox : dimensionToGroupByBoxes) {
public Collection<FunctionDTO> getDimensionsToGroupBy() {
Collection<FunctionDTO> dimensionsToGroupBy = new ArrayList<FunctionDTO>();
for (ValueListBox<FunctionDTO> dimensionListBox : dimensionToGroupByBoxes) {
if (dimensionListBox.getValue() != null) {
dimensionsToGroupBy.add(dimensionListBox.getValue());
}
@@ -118,7 +147,7 @@ public class RestrictedGroupingProvider implements GroupingProvider {
public void applyQueryDefinition(QueryDefinitionDeprecated queryDefinition) {
if (queryDefinition.getGrouperType() == GrouperType.Dimensions) {
int index = 0;
for (DimensionIdentifier dimension : queryDefinition.getDimensionsToGroupBy()) {
for (FunctionDTO dimension : queryDefinition.getDimensionsToGroupBy()) {
dimensionToGroupByBoxes.get(index).setValue(dimension, true);
index++;
}
@@ -23,11 +23,11 @@ import com.sap.sailing.gwt.ui.client.shared.panels.ResizingFlowPanel;
import com.sap.sailing.gwt.ui.datamining.DataMiningControls;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.GroupingChangedListener;
import com.sap.sailing.gwt.ui.datamining.GroupingProvider;
import com.sap.sailing.gwt.ui.datamining.SelectionChangedListener;
import com.sap.sailing.gwt.ui.datamining.SelectionProvider;
import com.sap.sailing.gwt.ui.datamining.StatisticChangedListener;
import com.sap.sailing.gwt.ui.datamining.StatisticProvider;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public class QueryDefinitionProviderWithControls extends AbstractQueryDefinitionProvider implements DataMiningControls {
@@ -38,7 +38,7 @@ public class QueryDefinitionProviderWithControls extends AbstractQueryDefinition
private StatisticProvider statisticProvider;
private GroupingProvider groupBySelectionPanel;
private MultiDimensionalGroupingProvider groupBySelectionPanel;
public QueryDefinitionProviderWithControls(StringMessages stringMessages, SailingServiceAsync sailingService, DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter) {
super(stringMessages, sailingService, dataMiningService, errorReporter);
@@ -74,12 +74,13 @@ public class QueryDefinitionProviderWithControls extends AbstractQueryDefinition
statisticProvider.addStatisticChangedListener(new StatisticChangedListener() {
@Override
public void statisticChanged() {
groupBySelectionPanel.updateAvailableDimensions(statisticProvider.getExtractionFunction());
notifyQueryDefinitionChanged();
}
});
functionsPanel.add(statisticProvider.getEntryWidget());
groupBySelectionPanel = new RestrictedGroupingProvider(getStringMessages());
groupBySelectionPanel = new MultiDimensionalGroupingProvider(getStringMessages(), getDataMiningService(), getErrorReporter());
groupBySelectionPanel.addGroupingChangedListener(new GroupingChangedListener() {
@Override
public void groupingChanged() {
@@ -112,7 +113,7 @@ public class QueryDefinitionProviderWithControls extends AbstractQueryDefinition
switch (queryDTO.getGrouperType()) {
case Dimensions:
default:
for (DimensionIdentifier dimension : groupBySelectionPanel.getDimensionsToGroupBy()) {
for (FunctionDTO dimension : groupBySelectionPanel.getDimensionsToGroupBy()) {
queryDTO.appendDimensionToGroupBy(dimension);
}
break;
@@ -8,10 +8,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.factories.DataMiningFactory;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.QueryDefinitionDeprecated;
import com.sap.sailing.datamining.shared.SailingDataMiningSerializationDummy;
import com.sap.sailing.gwt.ui.datamining.DataMiningService;
@@ -69,20 +66,15 @@ public class DataMiningServiceImpl extends RemoteServiceServlet implements DataM
}
@Override
public Collection<FunctionDTO> getDimensionsFor(DataTypes dataType, String localeInfoName) {
Class<?> dataTypeBaseClass = getBaseClassFor(dataType);
public Collection<FunctionDTO> getDimensionsFor(FunctionDTO extractionFunction, String localeInfoName) {
Class<?> dataTypeBaseClass = getBaseClassFor(extractionFunction);
Collection<Function<?>> dimensions = getDataMiningServer().getFunctionProvider().getDimensionsFor(dataTypeBaseClass);
return functionsAsFunctionDTOs(dimensions, localeInfoName);
}
private Class<?> getBaseClassFor(DataTypes dataType) {
switch (dataType) {
case GPSFix:
return HasGPSFixContext.class;
case TrackedLegOfCompetitor:
return HasTrackedLegOfCompetitorContext.class;
}
throw new IllegalArgumentException("No base class for data type " + dataType);
private Class<?> getBaseClassFor(FunctionDTO extractionFunction) {
Function<?> function = getDataMiningServer().getFunctionProvider().getFunctionForDTO(extractionFunction);
return function.getDeclaringType();
}
private Collection<FunctionDTO> functionsAsFunctionDTOs(Collection<Function<?>> functions, String localeInfoName) {
@@ -20,6 +20,7 @@ import com.sap.sse.datamining.impl.functions.SimpleFunctionRegistry;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasLegContext;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasRaceContext;
import com.sap.sse.datamining.test.util.ExpectedFunctionRegistryUtil;
import com.sap.sse.datamining.test.util.TestsUtil;
public class TestDataMiningServer {
@@ -35,7 +36,7 @@ public class TestDataMiningServer {
FunctionRegistry registry = new SimpleFunctionRegistry();
FunctionProvider provider = new RegistryFunctionProvider(registry);
OpenClassesWithFunctionsProvider classesWithFunctionsProvider = new OpenClassesWithFunctionsProvider();
DataMiningServer server = new DataMiningServerImpl(registry, provider, classesWithFunctionsProvider);
DataMiningServer server = new DataMiningServerImpl(TestsUtil.getTestStringMessages(), registry, provider, classesWithFunctionsProvider);
assertThat("The function registry should be empty.",
server.getFunctionRegistry().getAllFunctions().isEmpty(),
@@ -58,7 +59,7 @@ public class TestDataMiningServer {
FunctionRegistry registry = new SimpleFunctionRegistry();
FunctionProvider provider = new RegistryFunctionProvider(registry);
OpenClassesWithFunctionsProvider classesWithFunctionsProvider = new OpenClassesWithFunctionsProvider();
DataMiningServer server = new DataMiningServerImpl(registry, provider, classesWithFunctionsProvider);
DataMiningServer server = new DataMiningServerImpl(TestsUtil.getTestStringMessages(), registry, provider, classesWithFunctionsProvider);
classesWithFunctionsProvider.internalClassesWithMarkedMethods = null;
classesWithFunctionsProvider.externalLibraryClasses = null;
@@ -8,4 +8,10 @@ Knots=Knoten
InKnots=in Knoten
DistanceTraveled=zurückgelegte Distanz
ResultSignifier={0} ({1})
SignifierInUnit={0} in {1}
SignifierInUnit={0} in {1}
Name=Name
LegType=Art des Schenkels
SailID=Segelnummer
Year=Jahr
LegNumber=Nummer des Schenkels
NationalityAcronym=Nationalität
@@ -8,4 +8,10 @@ Knots=knots
InKnots=in knots
DistanceTraveled=distance traveled
ResultSignifier={0} ({1})
SignifierInUnit={0} in {1}
SignifierInUnit={0} in {1}
Name=Name
LegType=Leg Type
SailID=Sail Number
Year=Year
LegNumber=Leg Number
NationalityAcronym=Nationality