Merge branch 'master' into bug1018

This commit is contained in:
Axel Uhl committed 2015-04-30 14:10:04 +02:00
commit 20481e6fbe
96 files changed
+5037 -4348

No files matched your search

@@ -2,9 +2,9 @@ package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Statistic;
import com.sap.sse.datamining.shared.data.Unit;
public interface HasTrackedLegOfCompetitorContext {
@@ -4,8 +4,8 @@ import java.io.Serializable;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Statistic;
import com.sap.sse.datamining.shared.data.Unit;
/**
* A speed, convertible in various units of measure. Can be negative.
@@ -4,12 +4,12 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.HashSet;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.ListBox;
@@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
@@ -4,9 +4,9 @@ import java.util.Date;
import com.github.gwtbootstrap.datetimepicker.client.ui.base.HasViewMode.ViewMode;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.event.logical.shared.AttachEvent.Handler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.logical.shared.AttachEvent.Handler;
import com.sap.sailing.gwt.ui.shared.BetterDateTimeBox;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.dialog.DialogUtils;
File diff suppressed because it is too large. Load diff
@@ -1161,6 +1161,8 @@ notCapableOfGeneratingACodeForIdentifier=I''m not capable of generating a code f
serverUrl=Server URL
rotatedFromTrueNorthClickToToggleWindUp=Rotated {0} degrees from true north.\nTap/click to toggle between wind-up and north-up map display
startLineToFirstMarkTriangle=Start to first mark ({0}m)
dataMiningComponentsHaveBeenUpdated=The Data-Mining components have been updated
dataMiningComponentsNeedReloadDialogMessage=Click Reload to reload the components now. This will discard the current displayed data and run a default query.\nClick Close to do nothing. The Data-Mining won''t work correctly, until the components have been reloaded.
noDataForEvent=There isn''t any data for the event yet.
countriesCount={0,number} countries
countriesCount[one]={0,number} country
@@ -0,0 +1,14 @@
package com.sap.sailing.gwt.ui.datamining;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.gwt.client.shared.components.Component;
public interface DataMiningComponentProvider extends Component<AbstractSettings> {
/**
* Tells the provider, that {@link #reloadComponents()} will be called in the future.
*/
public void awaitReloadComponents();
public void reloadComponents();
}
@@ -49,7 +49,7 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint {
DockLayoutPanel selectionDockPanel = new DockLayoutPanel(Unit.PX);
selectionDockPanel.addNorth(createLogoAndTitlePanel(), 68);
BufferingQueryDefinitionProviderWithControls queryDefinitionProviderWithControls = new BufferingQueryDefinitionProviderWithControls(session, getStringMessages(), sailingService, dataMiningService, this);
BufferingQueryDefinitionProviderWithControls queryDefinitionProviderWithControls = new BufferingQueryDefinitionProviderWithControls(session, getStringMessages(), dataMiningService, this);
queryDefinitionProviderWithControls.getEntryWidget().addStyleName("dataMiningPanel");
selectionDockPanel.add(queryDefinitionProviderWithControls.getEntryWidget());
@@ -1,18 +1,23 @@
package com.sap.sailing.gwt.ui.datamining;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.rpc.RemoteService;
import com.sap.sailing.datamining.shared.SailingDataMiningSerializationDummy;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.SSEDataMiningSerializationDummy;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface DataMiningService extends RemoteService {
Date getComponentsChangedTimepoint();
Iterable<FunctionDTO> getAllStatistics(String localeInfoName);
Iterable<FunctionDTO> getDimensionsFor(FunctionDTO statisticToCalculate, String localeInfoName);
@@ -20,7 +25,8 @@ public interface DataMiningService extends RemoteService {
Iterable<DataRetrieverChainDefinitionDTO> getDataRetrieverChainDefinitionsFor(FunctionDTO statisticToCalculate, String localeInfoName);
QueryResult<Set<Object>> getDimensionValuesFor(DataMiningSession session, DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, int retrieverLevel, Iterable<FunctionDTO> dimensionDTOs, String localeInfoName);
QueryResult<Set<Object>> getDimensionValuesFor(DataMiningSession session, DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, int retrieverLevel,
Iterable<FunctionDTO> dimensionDTOs, Map<Integer, Map<FunctionDTO, Collection<?>>> filterSelectionDTO, String localeInfoName);
<ResultType extends Number> QueryResult<ResultType> runQuery(DataMiningSession session, QueryDefinitionDTO queryDefinition);
@@ -1,19 +1,24 @@
package com.sap.sailing.gwt.ui.datamining;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.datamining.shared.SailingDataMiningSerializationDummy;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.SSEDataMiningSerializationDummy;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface DataMiningServiceAsync {
public void getComponentsChangedTimepoint(AsyncCallback<Date> asyncCallback);
void getAllStatistics(String localeInfoName, AsyncCallback<Iterable<FunctionDTO>> callback);
void getDimensionsFor(FunctionDTO statisticToCalculate, String localeInfoName, AsyncCallback<Iterable<FunctionDTO>> callback);
@@ -23,7 +28,9 @@ public interface DataMiningServiceAsync {
void getDataRetrieverChainDefinitionsFor(FunctionDTO statisticToCalculate, String localeInfoName,
AsyncCallback<Iterable<DataRetrieverChainDefinitionDTO>> callback);
void getDimensionValuesFor(DataMiningSession session, DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, int retrieverLevel, Iterable<FunctionDTO> dimensionDTOs, String localeInfoName, AsyncCallback<QueryResult<Set<Object>>> callback);
void getDimensionValuesFor(DataMiningSession session, DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO, int retrieverLevel,
Iterable<FunctionDTO> dimensionDTOs, Map<Integer, Map<FunctionDTO, Collection<?>>> filterSelectionDTO,
String localeInfoName, AsyncCallback<QueryResult<Set<Object>>> callback);
<ResultType extends Number> void runQuery(DataMiningSession session, QueryDefinitionDTO queryDefinition, AsyncCallback<QueryResult<ResultType>> callback);
@@ -1,11 +1,9 @@
package com.sap.sailing.gwt.ui.datamining;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.gwt.client.shared.components.Component;
public interface DataRetrieverChainDefinitionProvider extends Component<AbstractSettings> {
public interface DataRetrieverChainDefinitionProvider extends DataMiningComponentProvider, StatisticChangedListener {
public DataRetrieverChainDefinitionDTO getDataRetrieverChainDefinition();
@@ -1,6 +1,6 @@
package com.sap.sailing.gwt.ui.datamining;
public interface SelectionChangedListener {
public interface FilterSelectionChangedListener {
public void selectionChanged();
@@ -4,14 +4,12 @@ import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface FilterSelectionProvider extends Component<AbstractSettings> {
public interface FilterSelectionProvider extends DataMiningComponentProvider, DataRetrieverChainDefinitionChangedListener {
public void addSelectionChangedListener(SelectionChangedListener listener);
public void addSelectionChangedListener(FilterSelectionChangedListener listener);
public Map<Integer, Map<FunctionDTO, Collection<? extends Serializable>>> getSelection();
@@ -2,12 +2,10 @@ package com.sap.sailing.gwt.ui.datamining;
import java.util.Collection;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface GroupingProvider extends Component<AbstractSettings> {
public interface GroupingProvider extends DataMiningComponentProvider, StatisticChangedListener{
public Collection<FunctionDTO> getDimensionsToGroupBy();
public String getCustomGrouperScriptText();
@@ -1,6 +1,6 @@
package com.sap.sailing.gwt.ui.datamining;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
public interface QueryDefinitionChangedListener {
@@ -1,10 +1,8 @@
package com.sap.sailing.gwt.ui.datamining;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
public interface QueryDefinitionProvider extends Component<AbstractSettings> {
public interface QueryDefinitionProvider extends DataMiningComponentProvider {
public Iterable<String> validateQueryDefinition(QueryDefinitionDTO queryDefinition);
public QueryDefinitionDTO getQueryDefinition();
@@ -1,7 +1,7 @@
package com.sap.sailing.gwt.ui.datamining;
import com.sap.sailing.gwt.ui.datamining.settings.QueryRunnerSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.gwt.client.shared.components.Component;
public interface QueryRunner extends QueryDefinitionChangedListener, Component<QueryRunnerSettings> {
@@ -1,7 +1,7 @@
package com.sap.sailing.gwt.ui.datamining;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface StatisticChangedListener {
@@ -1,13 +1,11 @@
package com.sap.sailing.gwt.ui.datamining;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface StatisticProvider extends DataMiningComponentProvider {
public interface StatisticProvider extends Component<AbstractSettings> {
public FunctionDTO getStatisticToCalculate();
public AggregatorType getAggregatorType();
@@ -13,8 +13,8 @@ import com.sap.sailing.gwt.ui.datamining.ResultsPresenter;
import com.sap.sailing.gwt.ui.datamining.settings.QueryRunnerSettings;
import com.sap.sailing.gwt.ui.datamining.settings.QueryRunnerSettingsDialogComponent;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
@@ -19,14 +19,14 @@ import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionChangedList
import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionProvider;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionPresenter;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionProvider;
import com.sap.sailing.gwt.ui.datamining.SelectionChangedListener;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionChangedListener;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.LocalizedTypeDTO;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
public class PlainFilterSelectionPresenter implements FilterSelectionPresenter, SelectionChangedListener,
public class PlainFilterSelectionPresenter implements FilterSelectionPresenter, FilterSelectionChangedListener,
DataRetrieverChainDefinitionChangedListener {
private final FilterSelectionProvider filterSelectionProvider;
@@ -69,7 +69,7 @@ public class PlainFilterSelectionPresenter implements FilterSelectionPresenter,
boolean first = true;
for (Integer levelIndex : sortedLevels) {
Map<FunctionDTO, Collection<? extends Serializable>> levelSelection = selection.get(levelIndex);
LocalizedTypeDTO level = retrieverChain.getRetrievedDataTypesChain().get(levelIndex);
LocalizedTypeDTO level = retrieverChain.getRetrievedDataType(levelIndex);
RetrieverLevelFilterSelectionPresenter levelSelectionPresenter = new RetrieverLevelFilterSelectionPresenter(level, levelSelection);
if (!first) {
levelSelectionPresenter.getEntryWidget().getElement().getStyle().setMarginTop(5, Unit.PX);
@@ -2,39 +2,123 @@ package com.sap.sailing.gwt.ui.datamining.selection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sailing.gwt.ui.client.StringMessages;
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.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.gwt.client.ErrorReporter;
public abstract class AbstractQueryDefinitionProvider implements QueryDefinitionProvider {
private final StringMessages stringMessages;
private final SailingServiceAsync sailingService;
private final DataMiningServiceAsync dataMiningService;
private final ErrorReporter errorReporter;
private final Timer dataminingComponentsChangedTimer;
private final int timerDelayInMillis = 30 * 1000;
private Date componentsChangedTimepoint;
private final DialogBox componentsChangedDialog;
private boolean blockChangeNotification;
private final Set<QueryDefinitionChangedListener> listeners;
public AbstractQueryDefinitionProvider(StringMessages stringMessages, SailingServiceAsync sailingService,
DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter) {
public AbstractQueryDefinitionProvider(StringMessages stringMessages, DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter) {
this.stringMessages = stringMessages;
this.sailingService = sailingService;
this.dataMiningService = dataMiningService;
this.errorReporter = errorReporter;
dataminingComponentsChangedTimer = new Timer() {
@Override
public void run() {
getDataMiningService().getComponentsChangedTimepoint(new AsyncCallback<Date>() {
@Override
public void onFailure(Throwable caught) {
AbstractQueryDefinitionProvider.this.errorReporter.reportError("Error fetching components changed timepoint from the server: "
+ caught.getMessage());
dataminingComponentsChangedTimer.schedule(timerDelayInMillis);
}
@Override
public void onSuccess(Date componentsChangedTimepoint) {
if (componentsChangedTimepoint.after(AbstractQueryDefinitionProvider.this.componentsChangedTimepoint)) {
AbstractQueryDefinitionProvider.this.componentsChangedTimepoint = componentsChangedTimepoint;
componentsChangedDialog.center();
}
dataminingComponentsChangedTimer.schedule(timerDelayInMillis);
}
});
}
};
componentsChangedDialog = createComponentsChangedDialog();
blockChangeNotification = false;
listeners = new HashSet<QueryDefinitionChangedListener>();
getDataMiningService().getComponentsChangedTimepoint(new AsyncCallback<Date>() {
@Override
public void onFailure(Throwable caught) {
AbstractQueryDefinitionProvider.this.errorReporter.reportError("Error fetching components changed timepoint from the server: "
+ caught.getMessage());
}
@Override
public void onSuccess(Date componentsChangedTimepoint) {
AbstractQueryDefinitionProvider.this.componentsChangedTimepoint = componentsChangedTimepoint;
dataminingComponentsChangedTimer.schedule(timerDelayInMillis);
}
});
}
private DialogBox createComponentsChangedDialog() {
DialogBox componentsChangedDialog = new DialogBox(false, true);
componentsChangedDialog.setAnimationEnabled(true);
componentsChangedDialog.setText(getStringMessages().dataMiningComponentsHaveBeenUpdated());
VerticalPanel contentPanel = new VerticalPanel();
contentPanel.setSpacing(5);
contentPanel.add(new Label(getStringMessages().dataMiningComponentsNeedReloadDialogMessage()));
HorizontalPanel buttonPanel = new HorizontalPanel();
buttonPanel.setSpacing(5);
buttonPanel.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
contentPanel.add(buttonPanel);
Button reloadButton = new Button(getStringMessages().reload());
reloadButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
AbstractQueryDefinitionProvider.this.componentsChangedDialog.hide();
reloadComponents();
}
});
buttonPanel.add(reloadButton);
Button closeButton = new Button(getStringMessages().close());
closeButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
AbstractQueryDefinitionProvider.this.componentsChangedDialog.hide();
}
});
buttonPanel.add(closeButton);
componentsChangedDialog.setWidget(contentPanel);
return componentsChangedDialog;
}
@Override
public Iterable<String> validateQueryDefinition(QueryDefinitionDTO queryDefinition) {
Collection<String> errorMessages = new ArrayList<String>();
@@ -121,10 +205,6 @@ public abstract class AbstractQueryDefinitionProvider implements QueryDefinition
protected StringMessages getStringMessages() {
return stringMessages;
}
protected SailingServiceAsync getSailingService() {
return sailingService;
}
protected DataMiningServiceAsync getDataMiningService() {
return dataMiningService;
@@ -16,22 +16,24 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SplitLayoutPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.datamining.DataMiningControls;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionChangedListener;
import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionProvider;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionChangedListener;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionProvider;
import com.sap.sailing.gwt.ui.datamining.GroupingChangedListener;
import com.sap.sailing.gwt.ui.datamining.SelectionChangedListener;
import com.sap.sailing.gwt.ui.datamining.GroupingProvider;
import com.sap.sailing.gwt.ui.datamining.StatisticChangedListener;
import com.sap.sailing.gwt.ui.datamining.StatisticProvider;
import com.sap.sailing.gwt.ui.datamining.selection.filter.ListRetrieverChainFilterSelectionProvider;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.QueryDefinitionDTOImpl;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
@@ -46,70 +48,57 @@ public class BufferingQueryDefinitionProviderWithControls extends AbstractQueryD
*/
private static final int queryBufferTimeInMillis = 200;
private final ProviderListener providerListener;
/**
* This effects the incoming change notifications.<br>
* If <code>true</code>, the outgoing change notification is blocked and the next provider (in
* the hierarchy) is told to update its components. This will automatically be set to <code>false</code>
* when the last provider notifies a change and then the listeners will be notified.<br>
* See {@link BufferingQueryDefinitionProviderWithControls#ProviderListener} for the concrete implemenation.
*/
private boolean isReloading;
private final Timer queryDefinitionReleaseTimer;
private final DockLayoutPanel mainPanel;
private FlowPanel controlsPanel;
private StatisticProvider statisticProvider;
private SimpleDataRetrieverChainDefinitionProvider retrieverChainProvider;
private DataRetrieverChainDefinitionProvider retrieverChainProvider;
private GroupingProvider groupingProvider;
private FilterSelectionProvider filterSelectionProvider;
private MultiDimensionalGroupingProvider groupBySelectionPanel;
private FilterSelectionProvider selectionProvider;
public BufferingQueryDefinitionProviderWithControls(DataMiningSession session, StringMessages stringMessages, SailingServiceAsync sailingService, DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter) {
super(stringMessages, sailingService, dataMiningService, errorReporter);
mainPanel = new DockLayoutPanel(Unit.PX);
mainPanel.addNorth(createFunctionsPanel(), 92);
selectionProvider = new ListRetrieverChainFilterSelectionProvider(session, stringMessages, dataMiningService, errorReporter, retrieverChainProvider);
selectionProvider.addSelectionChangedListener(new SelectionChangedListener() {
@Override
public void selectionChanged() {
scheduleQueryDefinitionChanged();
}
});
mainPanel.add(selectionProvider.getEntryWidget());
public BufferingQueryDefinitionProviderWithControls(DataMiningSession session, StringMessages stringMessages, DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter) {
super(stringMessages, dataMiningService, errorReporter);
providerListener = new ProviderListener();
isReloading = false;
queryDefinitionReleaseTimer = new Timer() {
@Override
public void run() {
notifyQueryDefinitionChanged();
}
};
mainPanel = new DockLayoutPanel(Unit.PX);
mainPanel.addNorth(createFunctionsPanel(), 92);
filterSelectionProvider = new ListRetrieverChainFilterSelectionProvider(session, stringMessages, dataMiningService, errorReporter, retrieverChainProvider);
filterSelectionProvider.addSelectionChangedListener(providerListener);
mainPanel.add(filterSelectionProvider.getEntryWidget());
}
private Widget createFunctionsPanel() {
FlowPanel statisticAndRetrieverChainPanel = new FlowPanel();
statisticProvider = new SimpleStatisticProvider(getStringMessages(), getDataMiningService(), getErrorReporter());
statisticProvider.addStatisticChangedListener(new StatisticChangedListener() {
@Override
public void statisticChanged(FunctionDTO newStatisticToCalculate, AggregatorType newAggregatorType) {
scheduleQueryDefinitionChanged();
}
});
statisticProvider.addStatisticChangedListener(providerListener);
statisticAndRetrieverChainPanel.add(statisticProvider.getEntryWidget());
retrieverChainProvider = new SimpleDataRetrieverChainDefinitionProvider(getStringMessages(), getDataMiningService(), getErrorReporter(), statisticProvider);
retrieverChainProvider.addDataRetrieverChainDefinitionChangedListener(new DataRetrieverChainDefinitionChangedListener() {
@Override
public void dataRetrieverChainDefinitionChanged(DataRetrieverChainDefinitionDTO newDataRetrieverChainDefinition) {
scheduleQueryDefinitionChanged();
}
});
retrieverChainProvider.addDataRetrieverChainDefinitionChangedListener(providerListener);
statisticAndRetrieverChainPanel.add(retrieverChainProvider.getEntryWidget());
groupBySelectionPanel = new MultiDimensionalGroupingProvider(getStringMessages(), getDataMiningService(), getErrorReporter(), statisticProvider);
groupBySelectionPanel.addGroupingChangedListener(new GroupingChangedListener() {
@Override
public void groupingChanged() {
scheduleQueryDefinitionChanged();
}
});
ScrollPanel groupBySelectionScrollPanel = new ScrollPanel(groupBySelectionPanel.getEntryWidget());
groupingProvider = new MultiDimensionalGroupingProvider(getStringMessages(), getDataMiningService(), getErrorReporter(), statisticProvider);
groupingProvider.addGroupingChangedListener(providerListener);
ScrollPanel groupBySelectionScrollPanel = new ScrollPanel(groupingProvider.getEntryWidget());
controlsPanel = new FlowPanel();
controlsPanel.addStyleName("definitionProviderControls");
@@ -118,14 +107,23 @@ public class BufferingQueryDefinitionProviderWithControls extends AbstractQueryD
clearSelectionButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
selectionProvider.clearSelection();
filterSelectionProvider.clearSelection();
}
});
addControl(clearSelectionButton);
Button reloadButton = new Button(getStringMessages().reload());
reloadButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
reloadComponents();
}
});
addControl(reloadButton);
SplitLayoutPanel controlsSplitPanel = new SplitLayoutPanel(15);
controlsSplitPanel.addWest(new ScrollPanel(statisticAndRetrieverChainPanel), 800);
controlsSplitPanel.addEast(new ScrollPanel(controlsPanel), 130);
controlsSplitPanel.addEast(new ScrollPanel(controlsPanel), 150);
controlsSplitPanel.add(groupBySelectionScrollPanel);
return controlsSplitPanel;
}
@@ -134,16 +132,31 @@ public class BufferingQueryDefinitionProviderWithControls extends AbstractQueryD
queryDefinitionReleaseTimer.schedule(queryBufferTimeInMillis);
}
@Override
public void awaitReloadComponents() {
// Nothing to do here
}
@Override
public void reloadComponents() {
isReloading = true;
statisticProvider.awaitReloadComponents();
groupingProvider.awaitReloadComponents();
retrieverChainProvider.awaitReloadComponents();
filterSelectionProvider.awaitReloadComponents();
statisticProvider.reloadComponents();
}
@Override
public QueryDefinitionDTO getQueryDefinition() {
QueryDefinitionDTOImpl queryDTO = new QueryDefinitionDTOImpl(LocaleInfo.getCurrentLocale().getLocaleName(), statisticProvider.getStatisticToCalculate(),
statisticProvider.getAggregatorType(), retrieverChainProvider.getDataRetrieverChainDefinition());
for (FunctionDTO dimension : groupBySelectionPanel.getDimensionsToGroupBy()) {
for (FunctionDTO dimension : groupingProvider.getDimensionsToGroupBy()) {
queryDTO.appendDimensionToGroupBy(dimension);
}
for (Entry<Integer, Map<FunctionDTO, Collection<? extends Serializable>>> filterSelectionEntry : selectionProvider.getSelection().entrySet()) {
for (Entry<Integer, Map<FunctionDTO, Collection<? extends Serializable>>> filterSelectionEntry : filterSelectionProvider.getSelection().entrySet()) {
queryDTO.setFilterSelectionFor(filterSelectionEntry.getKey(), filterSelectionEntry.getValue());
}
@@ -155,8 +168,8 @@ public class BufferingQueryDefinitionProviderWithControls extends AbstractQueryD
setBlockChangeNotification(true);
statisticProvider.applyQueryDefinition(queryDefinition);
retrieverChainProvider.applyQueryDefinition(queryDefinition);
groupBySelectionPanel.applyQueryDefinition(queryDefinition);
selectionProvider.applySelection(queryDefinition);
groupingProvider.applyQueryDefinition(queryDefinition);
filterSelectionProvider.applySelection(queryDefinition);
setBlockChangeNotification(false);
scheduleQueryDefinitionChanged();
@@ -205,5 +218,49 @@ public class BufferingQueryDefinitionProviderWithControls extends AbstractQueryD
public String getDependentCssClassName() {
return "queryDefinitionProviderWithControls";
}
private class ProviderListener implements StatisticChangedListener, DataRetrieverChainDefinitionChangedListener,
GroupingChangedListener, FilterSelectionChangedListener {
@Override
public void statisticChanged(FunctionDTO newStatisticToCalculate, AggregatorType newAggregatorType) {
if (isReloading) {
groupingProvider.statisticChanged(statisticProvider.getStatisticToCalculate(), statisticProvider.getAggregatorType());
groupingProvider.reloadComponents();
retrieverChainProvider.statisticChanged(statisticProvider.getStatisticToCalculate(), statisticProvider.getAggregatorType());
retrieverChainProvider.reloadComponents();
} else {
scheduleQueryDefinitionChanged();
}
}
@Override
public void groupingChanged() {
if (!isReloading) {
scheduleQueryDefinitionChanged();
}
}
@Override
public void dataRetrieverChainDefinitionChanged(DataRetrieverChainDefinitionDTO newDataRetrieverChainDefinition) {
if (isReloading) {
filterSelectionProvider.dataRetrieverChainDefinitionChanged(retrieverChainProvider.getDataRetrieverChainDefinition());
filterSelectionProvider.reloadComponents();
} else {
scheduleQueryDefinitionChanged();
}
}
@Override
public void selectionChanged() {
if (isReloading) {
isReloading = false;
}
scheduleQueryDefinitionChanged();
}
}
}
@@ -1,189 +0,0 @@
package com.sap.sailing.gwt.ui.datamining.selection;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
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.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.ValueListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.sap.sailing.gwt.ui.client.shared.controls.AbstractObjectRenderer;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
class DimensionFilterSelectionProvider {
private final DataMiningServiceAsync dataMiningService;
private final ErrorReporter errorReporter;
private final DataMiningSession session;
private final RetrieverLevelFilterSelectionProvider retrieverLevelSelectionProvider;
private final FlowPanel mainPanel;
private final HorizontalPanel controlsPanel;
private final ValueListBox<FunctionDTO> dimensionListBox;
private final DimensionChangedHandler dimensionChangedHandler;
private final ToggleButton toggleFilterButton;
private final SimpleBusyIndicator busyIndicator;
private final FilterableSelectionTable<?> selectionTable;
public DimensionFilterSelectionProvider(DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter, DataMiningSession session,
RetrieverLevelFilterSelectionProvider retrieverLevelSelectionProvider) {
this.dataMiningService = dataMiningService;
this.errorReporter = errorReporter;
this.session = session;
this.retrieverLevelSelectionProvider = retrieverLevelSelectionProvider;
mainPanel = new FlowPanel();
controlsPanel = new HorizontalPanel();
controlsPanel.setSpacing(2);
mainPanel.add(controlsPanel);
dimensionListBox = new ValueListBox<FunctionDTO>(new AbstractObjectRenderer<FunctionDTO>() {
@Override
protected String convertObjectToString(FunctionDTO function) {
return function.getDisplayName();
}
});
dimensionChangedHandler = new DimensionChangedHandler();
dimensionListBox.addValueChangeHandler(dimensionChangedHandler);
controlsPanel.add(dimensionListBox);
toggleFilterButton = new ToggleButton("S");
toggleFilterButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
selectionTable.setFilteringEnabled(toggleFilterButton.isDown());
}
});
toggleFilterButton.setVisible(false);
controlsPanel.add(toggleFilterButton);
busyIndicator = new SimpleBusyIndicator(true, 0.7f);
busyIndicator.setVisible(false);
mainPanel.add(busyIndicator);
selectionTable = new FilterableSelectionTable<>();
selectionTable.setVisible(false);
mainPanel.add(selectionTable);
}
private class DimensionChangedHandler implements ValueChangeHandler<FunctionDTO> {
boolean firstChange = true;
Collection<?> selectionToBeApplied;
@Override
public void onValueChange(ValueChangeEvent<FunctionDTO> event) {
final FunctionDTO dimension = event.getValue();
if (dimension != null) {
Collection<FunctionDTO> dimensionDTOs = new ArrayList<>();
dimensionDTOs.add(dimension);
busyIndicator.setVisible(true);
dataMiningService.getDimensionValuesFor(session, retrieverLevelSelectionProvider
.getDataRetrieverChain(), retrieverLevelSelectionProvider.getRetrieverLevel(), dimensionDTOs,
LocaleInfo.getCurrentLocale().getLocaleName(), new AsyncCallback<QueryResult<Set<Object>>>() {
@Override
public void onSuccess(QueryResult<Set<Object>> result) {
GroupKey contentKey = new GenericGroupKey<FunctionDTO>(dimension);
List<?> content = new ArrayList<Object>(result.getResults().get(contentKey));
Collections.sort(content, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
});
selectionTable.setContent(content == null ? new ArrayList<>() : content);
if (selectionToBeApplied != null) {
selectionTable.setSelection(selectionToBeApplied);
selectionToBeApplied = null;
}
busyIndicator.setVisible(false);
selectionTable.setVisible(true);
toggleFilterButton.setVisible(true);
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error fetching the dimension values of " + dimension + ": "
+ caught.getMessage());
}
});
if (firstChange && retrieverLevelSelectionProvider.canAddDimensionFilter()) {
retrieverLevelSelectionProvider.createAndAddDimensionFilter();
}
firstChange = false;
} else if (retrieverLevelSelectionProvider.shouldRemoveDimensionFilter()) {
retrieverLevelSelectionProvider.removeDimensionFilter(DimensionFilterSelectionProvider.this);
firstChange = false;
} else {
selectionTable.clearSelection();
selectionTable.setContent(new ArrayList<>());
selectionTable.setVisible(false);
toggleFilterButton.setVisible(false);
firstChange = true;
}
retrieverLevelSelectionProvider.updateAvailableDimensions();
}
}
void setAvailableDimensions(Collection<FunctionDTO> availableDimensions) {
dimensionListBox.setAcceptableValues(availableDimensions);
}
public FunctionDTO getSelectedDimension() {
return dimensionListBox.getValue();
}
public Collection<? extends Serializable> getSelection() {
return selectionTable.getSelection();
}
void clearSelection() {
selectionTable.clearSelection();
}
void setSelectedDimensionAndValues(FunctionDTO functionDTO, Collection<?> selection) {
dimensionChangedHandler.firstChange = false;
dimensionChangedHandler.selectionToBeApplied = selection;
dimensionListBox.setValue(functionDTO, true);
}
void addSelectionChangeHandler(SelectionChangeEvent.Handler handler) {
selectionTable.addSelectionChangeHandler(handler);
}
public Widget getEntryWidget() {
return mainPanel;
}
public void resizeToHeight(int heightInPX) {
int widthInPX = controlsPanel.getOffsetWidth();
mainPanel.setSize(widthInPX + "px", heightInPX + "px");
int remainingHeightInPX = Math.max(0, heightInPX - controlsPanel.getOffsetHeight());
selectionTable.resizeTo(widthInPX, remainingHeightInPX);
}
}
@@ -6,7 +6,7 @@ import java.util.HashSet;
import java.util.Map;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public class ExtractionFunctionSet {
@@ -20,17 +20,16 @@ import com.sap.sailing.gwt.ui.client.shared.controls.AbstractObjectRenderer;
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.StatisticChangedListener;
import com.sap.sailing.gwt.ui.datamining.StatisticProvider;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.panels.HorizontalFlowPanel;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
public class MultiDimensionalGroupingProvider implements GroupingProvider, StatisticChangedListener {
public class MultiDimensionalGroupingProvider implements GroupingProvider {
private static final String GROUPING_PROVIDER_ELEMENT_STYLE = "groupingProviderElement";
@@ -42,6 +41,7 @@ public class MultiDimensionalGroupingProvider implements GroupingProvider, Stati
private final HorizontalFlowPanel mainPanel;
private final List<ValueListBox<FunctionDTO>> dimensionToGroupByBoxes;
private boolean isAwaitingReload;
private FunctionDTO currentStatisticToCalculate;
private final List<FunctionDTO> availableDimensions;
@@ -53,6 +53,7 @@ public class MultiDimensionalGroupingProvider implements GroupingProvider, Stati
listeners = new HashSet<GroupingChangedListener>();
currentStatisticToCalculate = null;
availableDimensions = new ArrayList<>();
isAwaitingReload = false;
dimensionToGroupByBoxes = new ArrayList<ValueListBox<FunctionDTO>>();
mainPanel = new HorizontalFlowPanel();
@@ -65,15 +66,28 @@ public class MultiDimensionalGroupingProvider implements GroupingProvider, Stati
statisticProvider.addStatisticChangedListener(this);
}
@Override
public void awaitReloadComponents() {
isAwaitingReload = true;
}
@Override
public void reloadComponents() {
isAwaitingReload = false;
updateAvailableDimensions();
}
@Override
public void statisticChanged(FunctionDTO newStatisticToCalculate, AggregatorType newAggregatorType) {
if (!Objects.equals(currentStatisticToCalculate, newStatisticToCalculate)) {
currentStatisticToCalculate = newStatisticToCalculate;
updateAvailableDimensionsFor();
if (!isAwaitingReload) {
updateAvailableDimensions();
}
}
}
private void updateAvailableDimensionsFor() {
private void updateAvailableDimensions() {
if (currentStatisticToCalculate != null) {
dataMiningService.getDimensionsFor(currentStatisticToCalculate, LocaleInfo.getCurrentLocale()
.getLocaleName(), new AsyncCallback<Iterable<FunctionDTO>>() {
@@ -83,11 +97,13 @@ public class MultiDimensionalGroupingProvider implements GroupingProvider, Stati
for (FunctionDTO dimension : dimensions) {
availableDimensions.add(dimension);
}
Collections.sort(availableDimensions);
ValueListBox<FunctionDTO> firstDimensionToGroupByBox = createDimensionToGroupByBox();
addDimensionToGroupByBoxAndUpdateAcceptableValues(firstDimensionToGroupByBox);
if (!availableDimensions.isEmpty()) {
Collections.sort(availableDimensions);
firstDimensionToGroupByBox.setValue(availableDimensions.iterator().next(), true);
} else {
notifyListeners();
}
}
@@ -20,18 +20,16 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionChangedListener;
import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionProvider;
import com.sap.sailing.gwt.ui.datamining.StatisticChangedListener;
import com.sap.sailing.gwt.ui.datamining.StatisticProvider;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
public class SimpleDataRetrieverChainDefinitionProvider implements DataRetrieverChainDefinitionProvider,
StatisticChangedListener {
public class SimpleDataRetrieverChainDefinitionProvider implements DataRetrieverChainDefinitionProvider {
private final StringMessages stringMessages;
private final DataMiningServiceAsync dataMiningService;
@@ -39,6 +37,7 @@ public class SimpleDataRetrieverChainDefinitionProvider implements DataRetriever
private final Set<DataRetrieverChainDefinitionChangedListener> listeners;
private FunctionDTO currentStatisticToCalculate;
private boolean isAwaitingReload;
private final HorizontalPanel mainPanel;
private final ValueListBox<DataRetrieverChainDefinitionDTO> retrieverChainsListBox;
@@ -50,6 +49,7 @@ public class SimpleDataRetrieverChainDefinitionProvider implements DataRetriever
this.errorReporter = errorReporter;
listeners = new HashSet<>();
currentStatisticToCalculate = null;
isAwaitingReload = false;
mainPanel = new HorizontalPanel();
mainPanel.setSpacing(5);
@@ -78,18 +78,28 @@ public class SimpleDataRetrieverChainDefinitionProvider implements DataRetriever
return retrieverChainsListBox;
}
@Override
public void awaitReloadComponents() {
isAwaitingReload = true;
}
@Override
public void reloadComponents() {
updateRetrieverChains();
}
@Override
public void statisticChanged(FunctionDTO newStatisticToCalculate, AggregatorType newAggregatorType) {
if (!Objects.equals(currentStatisticToCalculate, newStatisticToCalculate)) {
String currentSourceType = currentStatisticToCalculate == null ? null : currentStatisticToCalculate.getSourceTypeName();
currentStatisticToCalculate = newStatisticToCalculate;
if (!Objects.equals(currentSourceType, newStatisticToCalculate.getSourceTypeName())) {
updateAvailableRetrieverChains();
if (!isAwaitingReload && !Objects.equals(currentSourceType, newStatisticToCalculate.getSourceTypeName())) {
updateRetrieverChains();
}
}
}
private void updateAvailableRetrieverChains() {
private void updateRetrieverChains() {
dataMiningService.getDataRetrieverChainDefinitionsFor(currentStatisticToCalculate, LocaleInfo.getCurrentLocale().getLocaleName(),
new AsyncCallback<Iterable<DataRetrieverChainDefinitionDTO>>() {
@Override
@@ -109,9 +119,10 @@ public class SimpleDataRetrieverChainDefinitionProvider implements DataRetriever
retrieverChainsListBox.setValue(retrieverChainToBeSelected);
retrieverChainsListBox.setAcceptableValues(sortedRetrieverChains);
if (!retrieverChainToBeSelected.equals(currentRetrieverChain)) {
if (isAwaitingReload || !retrieverChainToBeSelected.equals(currentRetrieverChain)) {
notifyListeners();
}
isAwaitingReload = false;
} else {
retrieverChainsListBox.setValue(null);
retrieverChainsListBox.setAcceptableValues(new ArrayList<DataRetrieverChainDefinitionDTO>());
@@ -121,6 +132,7 @@ public class SimpleDataRetrieverChainDefinitionProvider implements DataRetriever
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error retrieving the available DataRetrieverChainDefinitions: " + caught.getMessage());
isAwaitingReload = false;
}
});
}
@@ -23,9 +23,9 @@ import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.StatisticChangedListener;
import com.sap.sailing.gwt.ui.datamining.StatisticProvider;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
@@ -68,6 +68,16 @@ public class SimpleStatisticProvider implements StatisticProvider {
updateExtractionFunctions();
}
@Override
public void awaitReloadComponents() {
// Nothing to do here.
}
@Override
public void reloadComponents() {
updateExtractionFunctions();
}
private void updateExtractionFunctions() {
dataMiningService.getAllStatistics(LocaleInfo.getCurrentLocale().getLocaleName(), new AsyncCallback<Iterable<FunctionDTO>>() {
@@ -78,24 +88,14 @@ public class SimpleStatisticProvider implements StatisticProvider {
if (extractionFunctions.iterator().hasNext()) {
extractionFunctionSet.addAll(extractionFunctions);
StrippedFunctionDTO previousExtractionFunction = extractionFunctionListBox.getValue();
updateExtractionFunctionListBox();
StrippedFunctionDTO newExtractionFunction = extractionFunctionListBox.getValue();
String previousBaseDataType = baseDataTypeListBox.getValue();
updateBaseDataTypeListBox();
String newBaseDataType = baseDataTypeListBox.getValue();
if (!newExtractionFunction.equals(previousExtractionFunction) ||
!newBaseDataType.equals(previousBaseDataType)) {
notifyListeners();
}
} else {
clearListBox(extractionFunctionListBox);
clearListBox(baseDataTypeListBox);
notifyListeners();
}
notifyListeners();
}
@Override
@@ -1,8 +0,0 @@
package com.sap.sailing.gwt.ui.datamining.selection;
interface SizeProvider {
public int getFreeWidthInPX();
public int getFreeHeightInPX();
}
@@ -3,7 +3,7 @@ package com.sap.sailing.gwt.ui.datamining.selection;
import java.util.ArrayList;
import java.util.List;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public class StrippedFunctionDTO implements Comparable<StrippedFunctionDTO> {
@@ -0,0 +1,171 @@
package com.sap.sailing.gwt.ui.datamining.selection.filter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionModel.AbstractSelectionModel;
import com.google.gwt.view.client.SetSelectionModel;
/**
* A multi selection model, that allows to block the selection change notifications.<br>
* This is a copy of {@link MultiSelectionModel}, because the implementation of <code>MultiSelectionModel</code>
* wasn't open enough.
* @author Lennart Hensler (D054527)
*/
public class ControllableMultiSelectionModel<T> extends AbstractSelectionModel<T>
implements SetSelectionModel<T> {
// Ensure one value per key
private final Map<Object, T> selectedSet;
/**
* A map of keys to the item and its pending selection state.
*/
private final Map<Object, SelectionChange<T>> selectionChanges;
private boolean blockNotifications;
/**
* Constructs a MultiSelectionModel without a key provider.
*/
public ControllableMultiSelectionModel() {
this(null);
}
/**
* Constructs a MultiSelectionModel with the given key provider.
*
* @param keyProvider
* an instance of ProvidesKey<T>, or null if the item should act as its own key
*/
public ControllableMultiSelectionModel(ProvidesKey<T> keyProvider) {
super(keyProvider);
this.selectedSet = new HashMap<Object, T>();
this.selectionChanges = new HashMap<Object, SelectionChange<T>>();
blockNotifications = false;
}
public void setBlockNotifications(boolean blockNotifications) {
this.blockNotifications = blockNotifications;
}
/**
* Deselect all selected values.
*/
@Override
public void clear() {
// Clear the current list of pending changes.
selectionChanges.clear();
/*
* Add a pending change to deselect each key that is currently selected. We cannot just clear the selected set,
* because then we would not know which keys were selected before we cleared, which we need to know to determine
* if we should fire an event.
*/
for (T value : selectedSet.values()) {
selectionChanges.put(getKey(value), new SelectionChange<T>(value, false));
}
scheduleSelectionChangeEvent();
}
/**
* Get the set of selected items as a copy. If multiple selected items share the same key, only the last selected
* item is included in the set.
*
* @return the set of selected items
*/
@Override
public Set<T> getSelectedSet() {
resolveChanges();
return new HashSet<T>(selectedSet.values());
}
@Override
public boolean isSelected(T item) {
resolveChanges();
return selectedSet.containsKey(getKey(item));
}
@Override
public void setSelected(T item, boolean selected) {
selectionChanges.put(getKey(item), new SelectionChange<T>(item, selected));
scheduleSelectionChangeEvent();
}
@Override
protected void scheduleSelectionChangeEvent() {
if (!blockNotifications) {
super.scheduleSelectionChangeEvent();
} else {
resolveChanges();
}
}
@Override
protected void fireSelectionChangeEvent() {
if (isEventScheduled()) {
setEventCancelled(true);
}
resolveChanges();
}
private void resolveChanges() {
if (selectionChanges.isEmpty()) {
return;
}
boolean changed = false;
for (Map.Entry<Object, SelectionChange<T>> entry : selectionChanges.entrySet()) {
Object key = entry.getKey();
SelectionChange<T> value = entry.getValue();
boolean selected = value.isSelected();
T oldValue = selectedSet.get(key);
if (selected) {
selectedSet.put(key, value.getItem());
Object oldKey = getKey(oldValue);
if (!changed) {
changed = (oldKey == null) ? (key != null) : !oldKey.equals(key);
}
} else {
if (oldValue != null) {
selectedSet.remove(key);
changed = true;
}
}
}
selectionChanges.clear();
// Fire a selection change event.
if (changed && !blockNotifications) {
SelectionChangeEvent.fire(this);
}
}
/**
* Stores an item and its pending selection state.
* @param <T> the data type of the item
*/
private static class SelectionChange<T> {
private final T item;
private final boolean isSelected;
SelectionChange(T item, boolean isSelected) {
this.item = item;
this.isSelected = isSelected;
}
public T getItem() {
return item;
}
public boolean isSelected() {
return isSelected;
}
}
}
@@ -0,0 +1,243 @@
package com.sap.sailing.gwt.ui.datamining.selection.filter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
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.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.ValueListBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.client.shared.controls.AbstractObjectRenderer;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionChangedListener;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
class DimensionFilterSelectionProvider {
private final DataMiningServiceAsync dataMiningService;
private final ErrorReporter errorReporter;
private final DataMiningSession session;
private final RetrieverLevelFilterSelectionProvider retrieverLevelSelectionProvider;
private final FlowPanel mainPanel;
private final HorizontalPanel controlsPanel;
private final ValueListBox<FunctionDTO> dimensionListBox;
private final DimensionChangedHandler dimensionChangedHandler;
private final ToggleButton toggleFilterButton;
private final SimpleBusyIndicator busyIndicator;
private final FilterableSelectionTable<?> selectionTable;
private Collection<?> selectionToBeApplied;
public DimensionFilterSelectionProvider(DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter, DataMiningSession session,
RetrieverLevelFilterSelectionProvider retrieverLevelSelectionProvider) {
this.dataMiningService = dataMiningService;
this.errorReporter = errorReporter;
this.session = session;
this.retrieverLevelSelectionProvider = retrieverLevelSelectionProvider;
mainPanel = new FlowPanel();
controlsPanel = new HorizontalPanel();
controlsPanel.setSpacing(2);
mainPanel.add(controlsPanel);
dimensionListBox = new ValueListBox<FunctionDTO>(new AbstractObjectRenderer<FunctionDTO>() {
@Override
protected String convertObjectToString(FunctionDTO function) {
return function.getDisplayName();
}
});
dimensionChangedHandler = new DimensionChangedHandler();
dimensionListBox.addValueChangeHandler(dimensionChangedHandler);
controlsPanel.add(dimensionListBox);
toggleFilterButton = new ToggleButton("S");
toggleFilterButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
selectionTable.setFilteringEnabled(toggleFilterButton.isDown());
}
});
toggleFilterButton.setVisible(false);
controlsPanel.add(toggleFilterButton);
busyIndicator = new SimpleBusyIndicator(true, 0.7f);
busyIndicator.setVisible(false);
mainPanel.add(busyIndicator);
selectionTable = new FilterableSelectionTable<>();
selectionTable.addSelectionChangeHandler(new FilterSelectionChangedListener() {
@Override
public void selectionChanged() {
DimensionFilterSelectionProvider.this.retrieverLevelSelectionProvider.dimensionFilterSelectionChanged(DimensionFilterSelectionProvider.this);
}
});
selectionTable.setVisible(false);
mainPanel.add(selectionTable);
}
private class DimensionChangedHandler implements ValueChangeHandler<FunctionDTO> {
boolean firstChange = true;
@Override
public void onValueChange(ValueChangeEvent<FunctionDTO> event) {
final FunctionDTO dimension = event.getValue();
if (dimension != null) {
fetchAndSetAvailableData();
if (firstChange && retrieverLevelSelectionProvider.canAddDimensionSelectionProvider()) {
retrieverLevelSelectionProvider.createAndAddDimensionSelectionProvider();
}
firstChange = false;
} else if (retrieverLevelSelectionProvider.shouldRemoveDimensionSelectionProvider()) {
retrieverLevelSelectionProvider.removeDimensionFilter(DimensionFilterSelectionProvider.this);
firstChange = false;
} else {
selectionTable.clearSelection();
selectionTable.setContent(new ArrayList<>(), true);
selectionTable.setVisible(false);
toggleFilterButton.setVisible(false);
firstChange = true;
}
retrieverLevelSelectionProvider.updateAvailableDimensions();
}
}
private void fetchAndSetAvailableData() {
fetchAndDisplayAvailableData(false, true, null);
}
void fetchAndUpdateAvailableData(final Iterator<DimensionFilterSelectionProvider> retrieverLevelSelectionProviderIterator) {
fetchAndDisplayAvailableData(true, false, retrieverLevelSelectionProviderIterator);
}
/**
* Fetches the dimension values from the server and displays it. The data is filtered by the current filter
* selection (of all retriever levels).
*
* @param isUpdate <code>true</code>, if the call should update the data and preserve the selection and
* <code>false</code>, if it should override the data and clear the selection.
* @param selectionChangedCallback An {@link AsyncCallback} to react, if the selection has been changed or not.
*/
private void fetchAndDisplayAvailableData(final boolean isUpdate, final boolean notifyListenersWhenSelectionChanged,
final Iterator<DimensionFilterSelectionProvider> retrieverLevelSelectionProviderIterator) {
final FunctionDTO dimension = getSelectedDimension();
Collection<FunctionDTO> dimensionDTOs = new ArrayList<>();
dimensionDTOs.add(dimension);
@SuppressWarnings("unchecked")
Map<Integer, Map<FunctionDTO, Collection<?>>> filterSelectionDTO =
(Map<Integer, Map<FunctionDTO, Collection<?>>>)(Map<?, ?>) retrieverLevelSelectionProvider.getCompleteFilterSelection();
int retrieverLevel = retrieverLevelSelectionProvider.getRetrieverLevel();
if (filterSelectionDTO.containsKey(retrieverLevel)) {
filterSelectionDTO.get(retrieverLevel).remove(dimension);
}
busyIndicator.setVisible(true);
dataMiningService.getDimensionValuesFor(session, retrieverLevelSelectionProvider.getDataRetrieverChain(),
retrieverLevelSelectionProvider.getRetrieverLevel(), dimensionDTOs, filterSelectionDTO,
LocaleInfo.getCurrentLocale().getLocaleName(), new AsyncCallback<QueryResult<Set<Object>>>() {
@Override
public void onSuccess(QueryResult<Set<Object>> result) {
Map<GroupKey, Set<Object>> results = result.getResults();
List<Object> content = new ArrayList<Object>();
if (!results.isEmpty()) {
GroupKey contentKey = new GenericGroupKey<FunctionDTO>(dimension);
content.addAll(results.get(contentKey));
Collections.sort(content, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
});
}
boolean selectionChanged;
if (!isUpdate || content.isEmpty()) {
selectionChanged = selectionTable.setContent(content, notifyListenersWhenSelectionChanged);
} else {
selectionChanged = selectionTable.updateContent(content, notifyListenersWhenSelectionChanged);
}
if (selectionToBeApplied != null) {
selectionTable.setSelection(selectionToBeApplied, notifyListenersWhenSelectionChanged);
selectionToBeApplied = null;
}
busyIndicator.setVisible(false);
selectionTable.setVisible(true);
toggleFilterButton.setVisible(true);
if (retrieverLevelSelectionProviderIterator != null) {
if (selectionChanged) {
//Update the complete retriever level, because the selection changed
retrieverLevelSelectionProvider.updateAvailableData(getSelectedDimension());
} else {
//Continue with the update of the retriever level selection provider
retrieverLevelSelectionProvider.updateAvailableData(getSelectedDimension(), retrieverLevelSelectionProviderIterator);
}
}
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error fetching the dimension values of " + dimension + ": "
+ caught.getMessage());
}
});
}
void setAvailableDimensions(Collection<FunctionDTO> availableDimensions) {
dimensionListBox.setAcceptableValues(availableDimensions);
}
public FunctionDTO getSelectedDimension() {
return dimensionListBox.getValue();
}
public Collection<? extends Serializable> getSelection() {
return selectionTable.getSelection();
}
void clearSelection() {
selectionTable.clearSelection();
}
void setSelectedDimensionAndValues(FunctionDTO functionDTO, Collection<?> selection) {
dimensionChangedHandler.firstChange = false;
selectionToBeApplied = selection;
dimensionListBox.setValue(functionDTO, true);
}
public Widget getEntryWidget() {
return mainPanel;
}
public void resizeToHeight(int heightInPX) {
int widthInPX = controlsPanel.getOffsetWidth();
mainPanel.setSize(widthInPX + "px", heightInPX + "px");
int remainingHeightInPX = Math.max(0, heightInPX - controlsPanel.getOffsetHeight());
selectionTable.resizeTo(widthInPX, remainingHeightInPX);
}
}
@@ -1,20 +1,24 @@
package com.sap.sailing.gwt.ui.datamining.selection;
package com.sap.sailing.gwt.ui.datamining.selection.filter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionChangedListener;
import com.sap.sse.gwt.client.panels.AbstractFilterablePanel;
public class FilterableSelectionTable<ContentType extends Serializable> extends FlowPanel {
private final Set<FilterSelectionChangedListener> listeners;
private final Collection<ContentType> allData;
private int width;
private int height;
@@ -22,10 +26,12 @@ public class FilterableSelectionTable<ContentType extends Serializable> extends
private final AbstractFilterablePanel<ContentType> filterPanel;
private String filterText;
private final DataGrid<ContentType> table;
private final MultiSelectionModel<ContentType> selectionModel;
private final ControllableMultiSelectionModel<ContentType> selectionModel;
private final ListDataProvider<ContentType> dataProvider;
public FilterableSelectionTable() {
listeners = new HashSet<>();
allData = new ArrayList<ContentType>();
table = new DataGrid<ContentType>();
@@ -40,7 +46,13 @@ public class FilterableSelectionTable<ContentType extends Serializable> extends
};
table.addColumn(contentColumn);
selectionModel = new MultiSelectionModel<ContentType>();
selectionModel = new ControllableMultiSelectionModel<ContentType>();
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
notifyListeners();
}
});
table.setSelectionModel(selectionModel);
dataProvider = new ListDataProvider<ContentType>(new ProvidesKey<ContentType>() {
@@ -72,36 +84,110 @@ public class FilterableSelectionTable<ContentType extends Serializable> extends
private String getElementAsString(ContentType element) {
return element.toString();
}
/**
* Replaces the current content of the table with the new one and clears the current selection.<br>
* Returns <code>true</code> and notifies the listeners, if the selection changed.
* @param newContent
*/
@SuppressWarnings("unchecked") //You can't use instanceof for generic type parameters
public void setContent(Collection<?> newContent) {
public boolean setContent(Collection<?> newContent, boolean notifyListenersWhenSelectionChanged) {
Collection<ContentType> specificNewContent = null;
try {
specificNewContent = (Collection<ContentType>) newContent;
} catch (ClassCastException e) {
return;
return false;
}
internalSetContent(specificNewContent);
Set<ContentType> previousSelection = selectionModel.getSelectedSet();
if (notifyListenersWhenSelectionChanged) {
clearSelection();
} else {
selectionModel.setBlockNotifications(true);
clearSelection();
selectionModel.setBlockNotifications(false);
}
return !previousSelection.isEmpty();
}
/**
* Replaces the current content of the table with the new one, while preserving the current selection.<br>
* Returns <code>true</code> and notifies the listeners, if previously selected elements have been removed.
* @param newContent
* @return <code>true</code>, if previously selected elements have been removed.
*/
@SuppressWarnings("unchecked") //You can't use instanceof for generic type parameters
public boolean updateContent(Collection<?> newContent, boolean notifyListenersWhenSelectionChanged) {
Collection<ContentType> specificNewContent = null;
try {
specificNewContent = (Collection<ContentType>) newContent;
} catch (ClassCastException e) {
return false;
}
internalSetContent(specificNewContent);
return cleanSelection(notifyListenersWhenSelectionChanged);
}
private void internalSetContent(Collection<ContentType> specificNewContent) {
allData.clear();
allData.addAll(specificNewContent);
dataProvider.getList().clear();
dataProvider.getList().addAll(allData);
clearSelection();
filterPanel.updateAll(allData);
}
/**
* Unselects the selected elements, that aren't in the data anymore.
* @return <code>true</code>, if elements have been unselected;
*/
private boolean cleanSelection(boolean notifyListenersWhenSelectionChanged) {
boolean selectionChanged = false;
selectionModel.setBlockNotifications(true);
for (ContentType selectedElement : getSelection()) {
Object selectedElementKey = dataProvider.getKey(selectedElement);
boolean contentContainsSelectedElement = false;
for (ContentType contentElement : allData) {
if (selectedElementKey.equals(dataProvider.getKey(contentElement))) {
contentContainsSelectedElement = true;
break;
}
}
if (!contentContainsSelectedElement) {
selectionModel.setSelected(selectedElement, false);
selectionChanged = true;
}
}
selectionModel.setBlockNotifications(false);
if (selectionChanged && notifyListenersWhenSelectionChanged) {
notifyListeners();
}
return selectionChanged;
}
private void notifyListeners() {
for (FilterSelectionChangedListener listener : listeners) {
listener.selectionChanged();
}
}
public Collection<ContentType> getSelection() {
return selectionModel.getSelectedSet();
}
public void setSelection(Iterable<?> elements) {
public void setSelection(Iterable<?> elements, boolean notifyListenersWhenSelectionChanged) {
try {
@SuppressWarnings("unchecked") //You can't use instanceof for generic type parameters
Iterable<ContentType> specificContent = (Iterable<ContentType>) elements;
selectionModel.setBlockNotifications(!notifyListenersWhenSelectionChanged);
clearSelection();
for (ContentType element : specificContent) {
selectionModel.setSelected(element, true);
}
if (!notifyListenersWhenSelectionChanged) {
selectionModel.setBlockNotifications(false);
}
} catch (ClassCastException e) {/*Ignore the elements, because they don't match the ContentType*/}
}
@@ -109,8 +195,8 @@ public class FilterableSelectionTable<ContentType extends Serializable> extends
selectionModel.clear();
}
public void addSelectionChangeHandler(SelectionChangeEvent.Handler handler) {
selectionModel.addSelectionChangeHandler(handler);
public void addSelectionChangeHandler(FilterSelectionChangedListener handler) {
listeners.add(handler);
}
public boolean isFilteringEnabled() {
@@ -150,5 +236,4 @@ public class FilterableSelectionTable<ContentType extends Serializable> extends
table.redraw();
}
}
@@ -1,4 +1,4 @@
package com.sap.sailing.gwt.ui.datamining.selection;
package com.sap.sailing.gwt.ui.datamining.selection.filter;
import java.io.Serializable;
import java.util.Collection;
@@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
@@ -26,31 +27,32 @@ import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionChangedListener;
import com.sap.sailing.gwt.ui.datamining.DataRetrieverChainDefinitionProvider;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionChangedListener;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionPresenter;
import com.sap.sailing.gwt.ui.datamining.FilterSelectionProvider;
import com.sap.sailing.gwt.ui.datamining.SelectionChangedListener;
import com.sap.sailing.gwt.ui.datamining.presentation.PlainFilterSelectionPresenter;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.LocalizedTypeDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
public class ListRetrieverChainFilterSelectionProvider implements FilterSelectionProvider, DataRetrieverChainDefinitionChangedListener {
public class ListRetrieverChainFilterSelectionProvider implements FilterSelectionProvider {
private final DataMiningSession session;
private final StringMessages stringMessages;
private final DataMiningServiceAsync dataMiningService;
private final ErrorReporter errorReporter;
private final Set<SelectionChangedListener> listeners;
private final Set<FilterSelectionChangedListener> listeners;
private boolean isAwaitingReload;
private boolean blockDataUpdates;
private DataRetrieverChainDefinitionDTO retrieverChain;
private final Map<LocalizedTypeDTO, RetrieverLevelFilterSelectionProvider> selectionProvidersMappedByRetrieverLevel;
private final SelectionChangedListener retrieverLevelSelectionChangedListener;
private final Map<LocalizedTypeDTO, RetrieverLevelFilterSelectionProvider> selectionProvidersMappedByRetrievedDataType;
private final DockLayoutPanel mainPanel;
private final CellList<LocalizedTypeDTO> retrieverLevelList;
@@ -62,7 +64,7 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
public ListRetrieverChainFilterSelectionProvider(DataMiningSession session, StringMessages stringMessages,
DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter,
SimpleDataRetrieverChainDefinitionProvider retrieverChainProvider) {
DataRetrieverChainDefinitionProvider retrieverChainProvider) {
this.session = session;
this.stringMessages = stringMessages;
this.dataMiningService = dataMiningService;
@@ -70,15 +72,10 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
listeners = new HashSet<>();
retrieverChainProvider.addDataRetrieverChainDefinitionChangedListener(this);
isAwaitingReload = false;
blockDataUpdates = false;
retrieverChain = null;
selectionProvidersMappedByRetrieverLevel = new HashMap<>();
retrieverLevelSelectionChangedListener = new SelectionChangedListener() {
@Override
public void selectionChanged() {
mainPanel.setWidgetHidden(selectionPresenterScrollPanel, getSelection().isEmpty());
notifyListeners();
}
};
selectionProvidersMappedByRetrievedDataType = new HashMap<>();
retrieverLevelList = new CellList<LocalizedTypeDTO>(new RetrieverLevelCell());
retrieverLevelSelectionModel = new RetrieverLevelSelectionModel();
@@ -102,13 +99,25 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
mainPanel.setWidgetHidden(selectionPresenterScrollPanel, true);
}
@Override
public void awaitReloadComponents() {
isAwaitingReload = true;
}
@Override
public void reloadComponents() {
updateRetrievalLevels();
isAwaitingReload = false;
notifyListeners();
}
@Override
public void dataRetrieverChainDefinitionChanged(DataRetrieverChainDefinitionDTO newDataRetrieverChainDefinition) {
if (!Objects.equals(retrieverChain, newDataRetrieverChainDefinition)) {
retrieverChain = newDataRetrieverChainDefinition;
if (retrieverChain != null) {
if (!isAwaitingReload && retrieverChain != null) {
updateRetrievalLevels();
} else {
} else if (!isAwaitingReload) {
clearContent();
}
}
@@ -127,28 +136,38 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
@Override
public void onSuccess(Iterable<FunctionDTO> dimensions) {
Map<String, Collection<FunctionDTO>> dimensionsMappedBySourceType = mapBySourceType(dimensions);
int retrieverLevelIndex = 0;
LocalizedTypeDTO firstFilterableRetrieverLevel = null;
for (LocalizedTypeDTO retrieverLevel : retrieverChain.getRetrievedDataTypesChain()) {
String sourceTypeName = retrieverLevel.getTypeName();
if (dimensionsMappedBySourceType.containsKey(sourceTypeName) &&
!dimensionsMappedBySourceType.get(sourceTypeName).isEmpty()) {
firstFilterableRetrieverLevel = firstFilterableRetrieverLevel == null ? retrieverLevel : firstFilterableRetrieverLevel;
Map<Integer, Collection<FunctionDTO>> reducedDimensionsMappedByRetrieverLevel = reduceAndMapByRetrieverLevel(dimensionsMappedBySourceType);
int firstFilterableRetrieverLevel = Integer.MAX_VALUE;
for (Entry<Integer, Collection<FunctionDTO>> dimensionsEntry : reducedDimensionsMappedByRetrieverLevel.entrySet()) {
if (!dimensionsEntry.getValue().isEmpty()) {
int retrieverLevel = dimensionsEntry.getKey();
LocalizedTypeDTO retrievedDataType = retrieverChain.getRetrievedDataType(retrieverLevel);
RetrieverLevelFilterSelectionProvider selectionProvider =
new RetrieverLevelFilterSelectionProvider(session, dataMiningService, errorReporter, retrieverChain,
retrieverLevel, retrieverLevelIndex, selectionPanel);
selectionProvider.setAvailableDimensions(dimensionsMappedBySourceType.get(sourceTypeName));
selectionProvider.addSelectionChangedListener(retrieverLevelSelectionChangedListener);
selectionProvidersMappedByRetrieverLevel.put(retrieverLevel, selectionProvider);
new RetrieverLevelFilterSelectionProvider(session, dataMiningService, errorReporter, ListRetrieverChainFilterSelectionProvider.this, retrieverChain,
retrievedDataType, retrieverLevel, selectionPanel);
selectionProvider.setAvailableDimensions(dimensionsEntry.getValue());
selectionProvidersMappedByRetrievedDataType.put(retrievedDataType, selectionProvider);
firstFilterableRetrieverLevel = retrieverLevel < firstFilterableRetrieverLevel ? retrieverLevel : firstFilterableRetrieverLevel;
}
retrieverLevelIndex++;
}
retrieverLevelSelectionModel.setSelected(firstFilterableRetrieverLevel, true);
retrieverLevelSelectionModel.setSelected(retrieverChain.getRetrievedDataType(firstFilterableRetrieverLevel), true);
}
});
}
private void clearContent() {
blockDataUpdates = true;
retrieverLevelDataProvider.getList().clear();
retrieverLevelSelectionModel.clear();
selectionPanel.clear();
clearSelection();
selectionProvidersMappedByRetrievedDataType.clear();
blockDataUpdates = false;
forwardSelectionChanged();
}
private Map<String, Collection<FunctionDTO>> mapBySourceType(Iterable<FunctionDTO> dimensions) {
Map<String, Collection<FunctionDTO>> dimensionsMappedBySourceType = new HashMap<>();
for (FunctionDTO dimension : dimensions) {
@@ -159,19 +178,82 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
}
return dimensionsMappedBySourceType;
}
private Map<Integer, Collection<FunctionDTO>> reduceAndMapByRetrieverLevel(Map<String, Collection<FunctionDTO>> dimensionsMappedBySourceType) {
Map<Integer, Collection<FunctionDTO>> reducedDimensionsMappedBySourceType = new HashMap<>();
for (int retrieverLevel = 0; retrieverLevel < retrieverChain.size(); retrieverLevel++) {
LocalizedTypeDTO retrievedDataType = retrieverChain.getRetrievedDataType(retrieverLevel);
Collection<FunctionDTO> dimensions = dimensionsMappedBySourceType.get(retrievedDataType.getTypeName());
Collection<FunctionDTO> previousDimensions =
retrieverLevel > 0 ? dimensionsMappedBySourceType.get(retrieverChain.getRetrievedDataType(retrieverLevel - 1).getTypeName()) : null;
if (dimensions != null && !dimensions.isEmpty()) {
if (reducedDimensionsMappedBySourceType.isEmpty() || previousDimensions == null || previousDimensions.isEmpty()) {
reducedDimensionsMappedBySourceType.put(retrieverLevel, dimensions);
} else {
reducedDimensionsMappedBySourceType.put(retrieverLevel, reduce(dimensions, previousDimensions));
}
}
}
return reducedDimensionsMappedBySourceType;
}
private void clearContent() {
retrieverLevelDataProvider.getList().clear();
retrieverLevelSelectionModel.clear();
selectionPanel.clear();
clearSelection();
selectionProvidersMappedByRetrieverLevel.clear();
private Collection<FunctionDTO> reduce(Collection<FunctionDTO> dimensionsToReduce, Collection<FunctionDTO> byDimensions) {
Collection<FunctionDTO> reducedDimensions = new HashSet<>();
for (FunctionDTO dimension : dimensionsToReduce) {
boolean isDimensionAllowed = true;
for (FunctionDTO forbiddenDimension : byDimensions) {
if (areDimensionsLogicalEqual(dimension, forbiddenDimension)) {
isDimensionAllowed = false;
break;
}
}
if (isDimensionAllowed) {
reducedDimensions.add(dimension);
}
}
return reducedDimensions;
}
private boolean areDimensionsLogicalEqual(FunctionDTO dimension1, FunctionDTO dimension2) {
return dimension1.getDisplayName().equals(dimension2.getDisplayName()) &&
dimension1.getParameterTypeNames().equals(dimension2.getParameterTypeNames()) &&
dimension1.getReturnTypeName().equals(dimension2.getReturnTypeName());
}
void retrieverLevelFilterSelectionChanged(RetrieverLevelFilterSelectionProvider retrieverLevelFilterSelectionProvider, DimensionFilterSelectionProvider dimensionFilterSelectionProvider) {
if (!blockDataUpdates) {
updateFilterSelectionProviders(retrieverLevelFilterSelectionProvider.getRetrieverLevel(),
dimensionFilterSelectionProvider.getSelectedDimension());
}
}
void updateFilterSelectionProviders(int beginningWithLevel, final FunctionDTO exceptForDimension) {
LocalizedTypeDTO retrievedDataType = null;
for (int retrieverLevel = beginningWithLevel; retrieverLevel < retrieverChain.size(); retrieverLevel++) {
LocalizedTypeDTO levelRetrievedDataType = retrieverChain.getRetrievedDataType(retrieverLevel);
if (selectionProvidersMappedByRetrievedDataType.containsKey(levelRetrievedDataType)) {
retrievedDataType = levelRetrievedDataType;
break;
}
}
if (retrievedDataType != null) {
selectionProvidersMappedByRetrievedDataType.get(retrievedDataType).updateAvailableData(exceptForDimension);
} else {
//The update of the whole retriever chain is completed. Notify the listeners.
forwardSelectionChanged();
}
}
private void forwardSelectionChanged() {
mainPanel.setWidgetHidden(selectionPresenterScrollPanel, getSelection().isEmpty());
notifyListeners();
}
@Override
public Map<Integer, Map<FunctionDTO, Collection<? extends Serializable>>> getSelection() {
Map<Integer, Map<FunctionDTO, Collection<? extends Serializable>>> filterSelection = new HashMap<>();
for (RetrieverLevelFilterSelectionProvider selectionProvider : selectionProvidersMappedByRetrieverLevel.values()) {
for (RetrieverLevelFilterSelectionProvider selectionProvider : selectionProvidersMappedByRetrievedDataType.values()) {
Map<FunctionDTO, Collection<? extends Serializable>> levelFilterSelection = selectionProvider.getFilterSelection();
if (!levelFilterSelection.isEmpty()) {
filterSelection.put(selectionProvider.getRetrieverLevel(),
@@ -183,7 +265,7 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
@Override
public void applySelection(QueryDefinitionDTO queryDefinition) {
for (RetrieverLevelFilterSelectionProvider selectionProvider : selectionProvidersMappedByRetrieverLevel.values()) {
for (RetrieverLevelFilterSelectionProvider selectionProvider : selectionProvidersMappedByRetrievedDataType.values()) {
Map<Integer, Map<FunctionDTO, Collection<? extends Serializable>>> filterSelection = queryDefinition.getFilterSelection();
int retrieverLevel = selectionProvider.getRetrieverLevel();
if (filterSelection.containsKey(retrieverLevel)) {
@@ -194,18 +276,18 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
@Override
public void clearSelection() {
for (RetrieverLevelFilterSelectionProvider selectionProvider : selectionProvidersMappedByRetrieverLevel.values()) {
for (RetrieverLevelFilterSelectionProvider selectionProvider : selectionProvidersMappedByRetrievedDataType.values()) {
selectionProvider.clearSelection();
}
}
@Override
public void addSelectionChangedListener(SelectionChangedListener listener) {
public void addSelectionChangedListener(FilterSelectionChangedListener listener) {
listeners.add(listener);
}
private void notifyListeners() {
for (SelectionChangedListener listener : listeners) {
for (FilterSelectionChangedListener listener : listeners) {
listener.selectionChanged();
}
}
@@ -235,14 +317,14 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
selectionPanel.setWidget(selectionProvidersMappedByRetrieverLevel.get(retrieverLevelSelectionModel.getSelectedObject()).getEntryWidget());
selectionPanel.setWidget(selectionProvidersMappedByRetrievedDataType.get(retrieverLevelSelectionModel.getSelectedObject()).getEntryWidget());
}
});
}
@Override
public void setSelected(LocalizedTypeDTO item, boolean selected) {
if (!selected || !selectionProvidersMappedByRetrieverLevel.containsKey(item)) {
if (!selected || !selectionProvidersMappedByRetrievedDataType.containsKey(item)) {
//Prevents the selection of retriever levels, that don't have any dimensions and can't filter
return;
}
@@ -251,7 +333,7 @@ public class ListRetrieverChainFilterSelectionProvider implements FilterSelectio
}
}
private class SizeProvidingScrollPanel extends CustomScrollPanel implements SizeProvider {
private class SizeProvidingScrollPanel extends CustomScrollPanel implements RetrieverLevelFilterSelectionProvider.SizeProvider {
@Override
public int getFreeWidthInPX() {
return getOffsetWidth() - getVerticalScrollbar().asWidget().getOffsetWidth();
@@ -1,26 +1,23 @@
package com.sap.sailing.gwt.ui.datamining.selection;
package com.sap.sailing.gwt.ui.datamining.selection.filter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ProvidesResize;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.sap.sailing.gwt.ui.datamining.DataMiningServiceAsync;
import com.sap.sailing.gwt.ui.datamining.SelectionChangedListener;
import com.sap.sse.common.settings.AbstractSettings;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.LocalizedTypeDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.shared.components.Component;
@@ -30,40 +27,33 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
private final DataMiningServiceAsync dataMiningService;
private final ErrorReporter errorReporter;
private final Set<SelectionChangedListener> listeners;
private final DataMiningSession session;
private final ListRetrieverChainFilterSelectionProvider retrieverChainSelectionProvider;
private final DataRetrieverChainDefinitionDTO retrieverChain;
private final LocalizedTypeDTO retrievedDataType;
private final int retrieverLevel;
private final Collection<FunctionDTO> availableDimensions;
private final HorizontalLayoutPanel mainPanel;
private final Collection<DimensionFilterSelectionProvider> dimensionFilters;
private final SelectionChangeEvent.Handler selectionTablesChangedListener;
private final Collection<DimensionFilterSelectionProvider> dimensionSelectionProviders;
private final SizeProvider sizeProvider;
public RetrieverLevelFilterSelectionProvider(DataMiningSession session, DataMiningServiceAsync dataMiningService,
ErrorReporter errorReporter, DataRetrieverChainDefinitionDTO retrieverChain,
ErrorReporter errorReporter, ListRetrieverChainFilterSelectionProvider retrieverChainSelectionProvider, DataRetrieverChainDefinitionDTO retrieverChain,
LocalizedTypeDTO retrievedDataType, int retrieverLevel, SizeProvider sizeProvider) {
this.dataMiningService = dataMiningService;
this.errorReporter = errorReporter;
listeners = new HashSet<>();
this.session = session;
this.retrieverChainSelectionProvider = retrieverChainSelectionProvider;
this.retrieverChain = retrieverChain;
this.retrievedDataType = retrievedDataType;
this.retrieverLevel = retrieverLevel;
availableDimensions = new ArrayList<>();
mainPanel = new HorizontalLayoutPanel();
dimensionFilters = new ArrayList<>();
selectionTablesChangedListener = new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
notifyListeners();
}
};
dimensionSelectionProviders = new ArrayList<>();
this.sizeProvider = sizeProvider;
}
@@ -71,44 +61,43 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
public void setAvailableDimensions(Collection<FunctionDTO> dimensions) {
availableDimensions.clear();
availableDimensions.addAll(dimensions);
initializeDimensionFilters();
initializeDimensionSelectionProviders();
}
private void initializeDimensionFilters() {
DimensionFilterSelectionProvider dimensionFilter = createDimensionFilter();
private void initializeDimensionSelectionProviders() {
DimensionFilterSelectionProvider dimensionFilter = createDimensionSelectionProvider();
List<FunctionDTO> availableDimensionsList = new ArrayList<>(availableDimensions);
Collections.sort(availableDimensionsList);
dimensionFilter.setAvailableDimensions(availableDimensionsList);
addDimensionFilter(dimensionFilter);
addDimensionSelectionProvider(dimensionFilter);
}
boolean canAddDimensionFilter() {
boolean canAddDimensionSelectionProvider() {
return availableDimensions.size() != getSelectedDimensions().size();
}
void createAndAddDimensionFilter() {
addDimensionFilter(createDimensionFilter());
void createAndAddDimensionSelectionProvider() {
addDimensionSelectionProvider(createDimensionSelectionProvider());
}
private DimensionFilterSelectionProvider createDimensionFilter() {
private DimensionFilterSelectionProvider createDimensionSelectionProvider() {
DimensionFilterSelectionProvider dimensionFilter = new DimensionFilterSelectionProvider(dataMiningService, errorReporter, session, this);
dimensionFilter.addSelectionChangeHandler(selectionTablesChangedListener);
return dimensionFilter;
}
private void addDimensionFilter(DimensionFilterSelectionProvider dimensionFilter) {
dimensionFilters.add(dimensionFilter);
private void addDimensionSelectionProvider(DimensionFilterSelectionProvider dimensionFilter) {
dimensionSelectionProviders.add(dimensionFilter);
mainPanel.add(dimensionFilter.getEntryWidget());
mainPanel.onResize();
}
boolean shouldRemoveDimensionFilter() {
boolean shouldRemoveDimensionSelectionProvider() {
return availableDimensions.size() - getSelectedDimensions().size() > 1;
}
void removeDimensionFilter(DimensionFilterSelectionProvider dimensionFilter) {
dimensionFilter.clearSelection(); // Notifies the listeners, if values were selected
dimensionFilters.remove(dimensionFilter);
dimensionSelectionProviders.remove(dimensionFilter);
mainPanel.remove(dimensionFilter.getEntryWidget());
mainPanel.onResize();
}
@@ -116,7 +105,7 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
void updateAvailableDimensions() {
Collection<FunctionDTO> remainingDimensionsBase = new ArrayList<FunctionDTO>(availableDimensions);
remainingDimensionsBase.removeAll(getSelectedDimensions());
for (DimensionFilterSelectionProvider dimensionFilter : dimensionFilters) {
for (DimensionFilterSelectionProvider dimensionFilter : dimensionSelectionProviders) {
List<FunctionDTO> remainingDimensions = new ArrayList<>(remainingDimensionsBase);
FunctionDTO selectedDimension = dimensionFilter.getSelectedDimension();
if (selectedDimension != null) {
@@ -131,7 +120,7 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
private Collection<FunctionDTO> getSelectedDimensions() {
Collection<FunctionDTO> selectedDimensions = new ArrayList<>();
for (DimensionFilterSelectionProvider dimensionFilter : dimensionFilters) {
for (DimensionFilterSelectionProvider dimensionFilter : dimensionSelectionProviders) {
FunctionDTO selectedDimension = dimensionFilter.getSelectedDimension();
if (selectedDimension != null) {
selectedDimensions.add(selectedDimension);
@@ -139,10 +128,41 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
}
return selectedDimensions;
}
/**
* Updates the dimension values except for the given dimension.<br>
* Aborts the update, if it caused a selection change.
*/
void updateAvailableData(FunctionDTO exceptForDimension) {
updateAvailableData(exceptForDimension, dimensionSelectionProviders.iterator());
}
void updateAvailableData(final FunctionDTO exceptForDimension, final Iterator<DimensionFilterSelectionProvider> selectionProviderIterator) {
if (selectionProviderIterator.hasNext()) {
DimensionFilterSelectionProvider selectionProvider = selectionProviderIterator.next();
FunctionDTO selectedDimension = selectionProvider.getSelectedDimension();
if (selectedDimension != null && !selectedDimension.equals(exceptForDimension)) {
selectionProvider.fetchAndUpdateAvailableData(selectionProviderIterator);
} else {
updateAvailableData(exceptForDimension, selectionProviderIterator);
}
} else {
// Update for this level is completed. Continue with the next level.
retrieverChainSelectionProvider.updateFilterSelectionProviders(getRetrieverLevel() + 1, exceptForDimension);
}
}
void dimensionFilterSelectionChanged(DimensionFilterSelectionProvider dimensionFilterSelectionProvider) {
retrieverChainSelectionProvider.retrieverLevelFilterSelectionChanged(this, dimensionFilterSelectionProvider);
}
Map<Integer, Map<FunctionDTO, Collection<? extends Serializable>>> getCompleteFilterSelection() {
return retrieverChainSelectionProvider.getSelection();
}
public Map<FunctionDTO, Collection<? extends Serializable>> getFilterSelection() {
HashMap<FunctionDTO, Collection<? extends Serializable>> filterSelection = new HashMap<>();
for (DimensionFilterSelectionProvider dimensionFilter : dimensionFilters) {
for (DimensionFilterSelectionProvider dimensionFilter : dimensionSelectionProviders) {
Collection<? extends Serializable> dimensionFilterSelection = dimensionFilter.getSelection();
if (!dimensionFilterSelection.isEmpty()) {
filterSelection.put(dimensionFilter.getSelectedDimension(), dimensionFilterSelection);
@@ -152,15 +172,15 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
}
public void applySelection(Map<FunctionDTO, Collection<? extends Serializable>> filterSelection) {
dimensionFilters.clear();
dimensionSelectionProviders.clear();
mainPanel.clear();
List<FunctionDTO> sortedDimensions = new ArrayList<>(filterSelection.keySet());
Collections.sort(sortedDimensions);
for (FunctionDTO functionDTO : sortedDimensions) {
DimensionFilterSelectionProvider dimensionFilter = createDimensionFilter();
addDimensionFilter(dimensionFilter);
DimensionFilterSelectionProvider dimensionFilter = createDimensionSelectionProvider();
addDimensionSelectionProvider(dimensionFilter);
updateAvailableDimensions();
dimensionFilter.setSelectedDimensionAndValues(functionDTO, filterSelection.get(functionDTO));
}
@@ -168,21 +188,11 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
public void clearSelection() {
mainPanel.clear();
for (DimensionFilterSelectionProvider dimensionFilter : dimensionFilters) {
for (DimensionFilterSelectionProvider dimensionFilter : dimensionSelectionProviders) {
dimensionFilter.clearSelection();
}
dimensionFilters.clear();
initializeDimensionFilters();
}
public void addSelectionChangedListener(SelectionChangedListener listener) {
listeners.add(listener);
}
private void notifyListeners() {
for (SelectionChangedListener listener : listeners) {
listener.selectionChanged();
}
dimensionSelectionProviders.clear();
initializeDimensionSelectionProviders();
}
DataRetrieverChainDefinitionDTO getDataRetrieverChain() {
@@ -236,12 +246,19 @@ public class RetrieverLevelFilterSelectionProvider implements Component<Abstract
return "singleRetrieverLevelSelectionPanel";
}
interface SizeProvider {
public int getFreeWidthInPX();
public int getFreeHeightInPX();
}
private class HorizontalLayoutPanel extends HorizontalPanel implements RequiresResize, ProvidesResize {
@Override
public void onResize() {
int heightInPX = sizeProvider.getFreeHeightInPX();
setHeight(heightInPX + "px");
for (DimensionFilterSelectionProvider selectionProvider : dimensionFilters) {
for (DimensionFilterSelectionProvider selectionProvider : dimensionSelectionProviders) {
selectionProvider.resizeToHeight(heightInPX);
}
}
@@ -14,7 +14,6 @@ import com.sap.sailing.domain.common.LeaderboardType;
import com.sap.sailing.domain.common.dto.AbstractLeaderboardDTO;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardUrlSettings;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.shared.components.Component;
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
@@ -2,8 +2,11 @@ package com.sap.sailing.gwt.ui.server;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.osgi.framework.BundleContext;
@@ -21,11 +24,11 @@ import com.sap.sse.datamining.factories.FunctionDTOFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.impl.DataRetrieverTypeWithInformation;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.SSEDataMiningSerializationDummy;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.LocalizedTypeDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
@@ -56,6 +59,11 @@ public class DataMiningServiceImpl extends RemoteServiceServlet implements DataM
return dataMiningServerTracker.getService();
}
@Override
public Date getComponentsChangedTimepoint() {
return getDataMiningServer().getComponentsChangedTimepoint();
}
@Override
public Iterable<FunctionDTO> getAllStatistics(String localeInfoName) {
Iterable<Function<?>> statistics = getDataMiningServer().getAllStatistics();
@@ -124,11 +132,13 @@ public class DataMiningServiceImpl extends RemoteServiceServlet implements DataM
@Override
public QueryResult<Set<Object>> getDimensionValuesFor(DataMiningSession session, DataRetrieverChainDefinitionDTO dataRetrieverChainDefinitionDTO,
int retrieverLevel, Iterable<FunctionDTO> dimensionDTOs, String localeInfoName) {
DataRetrieverChainDefinition<RacingEventService, ?> retrieverChainDefinition = getDataMiningServer().getDataRetrieverChainDefinition(dataRetrieverChainDefinitionDTO.getId());
int retrieverLevel, Iterable<FunctionDTO> dimensionDTOs, Map<Integer, Map<FunctionDTO, Collection<?>>> filterSelectionDTO, String localeInfoName) {
DataMiningServer dataMiningServer = getDataMiningServer();
DataRetrieverChainDefinition<RacingEventService, ?> retrieverChainDefinition = dataMiningServer.getDataRetrieverChainDefinition(dataRetrieverChainDefinitionDTO.getId());
Iterable<Function<?>> dimensions = functionDTOsAsFunctions(dimensionDTOs);
Map<Integer, Map<Function<?>, Collection<?>>> filterSelection = filterSelectionDTOAsFilterSelection(filterSelectionDTO);
Locale locale = ResourceBundleStringMessages.Util.getLocaleFor(localeInfoName);
Query<Set<Object>> dimensionValuesQuery = getDataMiningServer().createDimensionValuesQuery(retrieverChainDefinition, retrieverLevel, dimensions, locale);
Query<Set<Object>> dimensionValuesQuery = dataMiningServer.createDimensionValuesQuery(retrieverChainDefinition, retrieverLevel, dimensions, filterSelection, locale);
// QueryResult<Set<Object>> result = getDataMiningServer().runNewQueryAndAbortPreviousQueries(session, dimensionValuesQuery);
QueryResult<Set<Object>> result = dimensionValuesQuery.run();
return result;
@@ -138,11 +148,34 @@ public class DataMiningServiceImpl extends RemoteServiceServlet implements DataM
List<Function<?>> functions = new ArrayList<>();
DataMiningServer dataMiningServer = getDataMiningServer();
for (FunctionDTO functionDTO : functionDTOs) {
functions.add(dataMiningServer.getFunctionForDTO(functionDTO));
Function<?> function = dataMiningServer.getFunctionForDTO(functionDTO);
if (function != null) {
functions.add(function);
}
}
return functions;
}
private Map<Integer, Map<Function<?>, Collection<?>>> filterSelectionDTOAsFilterSelection(
Map<Integer, Map<FunctionDTO, Collection<?>>> filterSelectionDTO) {
Map<Integer, Map<Function<?>, Collection<?>>> filterSelection = new HashMap<>();
for (Integer retrieverLevel : filterSelectionDTO.keySet()) {
Map<FunctionDTO, Collection<?>> retrievalLevelSelection = filterSelectionDTO.get(retrieverLevel);
for (FunctionDTO dimensionDTO : retrievalLevelSelection.keySet()) {
if (!retrievalLevelSelection.get(dimensionDTO).isEmpty()) {
Function<?> function = getDataMiningServer().getFunctionForDTO(dimensionDTO);
if (function != null) {
if (!filterSelection.containsKey(retrieverLevel)) {
filterSelection.put(retrieverLevel, new HashMap<Function<?>, Collection<?>>());
}
filterSelection.get(retrieverLevel).put(function, retrievalLevelSelection.get(dimensionDTO));
}
}
}
}
return filterSelection;
}
@Override
public <ResultType extends Number> QueryResult<ResultType> runQuery(DataMiningSession session, QueryDefinitionDTO queryDefinitionDTO) {
QueryDefinition<RacingEventService, ?, ResultType> queryDefinition = getDataMiningServer().getQueryDefinitionForDTO(queryDefinitionDTO);
@@ -6,6 +6,7 @@ import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.base.LatLng;
import com.google.gwt.maps.client.base.LatLngBounds;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.gwt.ui.client.shared.racemap.CoordinateSystem;
/**
* A field of vectors to display in a streamlet {@link Swarm}. The {@link Vector}s returned by {@link #getVector(Position, Date)}
@@ -57,7 +57,7 @@
<!-- Specify the paths for translatable code -->
<extend-property name="locale" values="en,de,cn,ru" />
<set-property name="locale" values="en,de,cn,ru" />
<set-property name="locale" value="en,de,cn,ru" />
<set-property-fallback name="locale" value="en"/>
<!-- Uncomment this to get clear-text CSS style/class names in generated output -->
@@ -33,7 +33,7 @@
<!-- Specify the paths for translatable code -->
<extend-property name="locale" values="en,de,cn,ru" />
<extend-property name="locale" values="en,de,cn,ru" />
<set-property name="locale" values="en,de,cn,ru" />
<set-property name="locale" value="en,de,cn,ru" />
<set-property-fallback name="locale" value="en"/>
<source path='common'/>
@@ -8,6 +8,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: com.sap.sse.datamining.shared,
com.sap.sse.datamining.shared.annotations,
com.sap.sse.datamining.shared.components,
com.sap.sse.datamining.shared.data,
com.sap.sse.datamining.shared.dto,
com.sap.sse.datamining.shared.impl,
com.sap.sse.datamining.shared.impl.dto
@@ -2,6 +2,8 @@ package com.sap.sse.datamining.shared;
import java.io.Serializable;
import com.sap.sse.datamining.shared.data.Unit;
public interface AdditionalResultData extends Serializable {
public int getRetrievedDataAmount();
@@ -3,5 +3,7 @@ package com.sap.sse.datamining.shared;
import java.io.Serializable;
public interface DataMiningSession extends Serializable {
public String asString();
}
@@ -3,6 +3,9 @@ package com.sap.sse.datamining.shared;
import java.io.Serializable;
import java.util.Map;
import com.sap.sse.datamining.shared.data.QueryResultState;
import com.sap.sse.datamining.shared.data.Unit;
public interface QueryResult<AggregatedType> extends Serializable {
public QueryResultState getState();
@@ -7,7 +7,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Locale;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
/**
* Methods marked with this annotation will be used as computable statistic for the data mining framework. The method will be called,
@@ -1,4 +1,4 @@
package com.sap.sse.datamining.shared;
package com.sap.sse.datamining.shared.data;
public enum Month {
@@ -1,4 +1,4 @@
package com.sap.sse.datamining.shared;
package com.sap.sse.datamining.shared.data;
public enum QueryResultState {
@@ -1,4 +1,4 @@
package com.sap.sse.datamining.shared;
package com.sap.sse.datamining.shared.data;
public enum Unit {
@@ -1,22 +0,0 @@
package com.sap.sse.datamining.shared.dto;
import java.io.Serializable;
import java.util.List;
public interface FunctionDTO extends Serializable, Comparable<FunctionDTO> {
public String getSourceTypeName();
public String getReturnTypeName();
public String getFunctionName();
public String getDisplayName();
public List<String> getParameterTypeNames();
public boolean isDimension();
public int getOrdinal();
}
@@ -1,4 +1,4 @@
package com.sap.sse.datamining.shared;
package com.sap.sse.datamining.shared.dto;
import java.io.Serializable;
import java.util.Collection;
@@ -6,8 +6,8 @@ import java.util.List;
import java.util.Map;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface QueryDefinitionDTO extends Serializable {
@@ -5,7 +5,14 @@ import com.sap.sse.datamining.shared.DataMiningSession;
public abstract class AbstractDataMiningSession implements DataMiningSession {
private static final long serialVersionUID = 4420076115971081397L;
//Enforce hash code and equals in all subclasses
@Override
public String asString() {
return toString();
}
//Enforce methods in all subclasses
@Override
public abstract String toString();
@Override
public abstract boolean equals(Object other);
@Override
@@ -1,7 +1,7 @@
package com.sap.sse.datamining.shared.impl;
import com.sap.sse.datamining.shared.AdditionalResultData;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
public class AdditionalResultDataImpl implements AdditionalResultData {
private static final long serialVersionUID = -9054872418326676943L;
@@ -1,7 +1,7 @@
package com.sap.sse.datamining.shared.impl;
import com.sap.sse.datamining.shared.AdditionalResultData;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
/**
* Null Object pattern for {@link AdditionalResultData} with the values:
@@ -6,8 +6,8 @@ import java.util.Map;
import com.sap.sse.datamining.shared.AdditionalResultData;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.QueryResultState;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.QueryResultState;
import com.sap.sse.datamining.shared.data.Unit;
public class QueryResultImpl<AggregatedType> implements QueryResult<AggregatedType> {
private static final long serialVersionUID = 5173796619174827696L;
@@ -45,9 +45,17 @@ public class DataRetrieverChainDefinitionDTO implements Serializable, Comparable
return retrievedDataTypesChain.get(retrievedDataTypesChain.size() - 1).getTypeName();
}
public List<LocalizedTypeDTO> getRetrievedDataTypesChain() {
public Collection<LocalizedTypeDTO> getRetrievedDataTypesChain() {
return retrievedDataTypesChain;
}
public int size() {
return retrievedDataTypesChain.size();
}
public LocalizedTypeDTO getRetrievedDataType(int retrieverLevel) {
return retrievedDataTypesChain.get(retrieverLevel);
}
@Override
public int compareTo(DataRetrieverChainDefinitionDTO d) {
@@ -1,11 +1,10 @@
package com.sap.sse.datamining.shared.impl.dto;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public class FunctionDTOImpl implements FunctionDTO {
public class FunctionDTO implements Serializable, Comparable<FunctionDTO> {
private static final long serialVersionUID = 4587389541910498505L;
private boolean isDimension;
@@ -21,10 +20,10 @@ public class FunctionDTOImpl implements FunctionDTO {
* Constructor for the GWT-Serialization. Don't use this!
*/
@Deprecated
FunctionDTOImpl() {
FunctionDTO() {
}
public FunctionDTOImpl(boolean isDimension, String functionName, String sourceTypeName, String returnTypeName,
public FunctionDTO(boolean isDimension, String functionName, String sourceTypeName, String returnTypeName,
List<String> parameterTypeNames, String displayName, int ordinal) {
this.isDimension = isDimension;
this.functionName = functionName;
@@ -36,37 +35,30 @@ public class FunctionDTOImpl implements FunctionDTO {
this.ordinal = ordinal;
}
@Override
public String getSourceTypeName() {
return sourceTypeName;
}
@Override
public String getReturnTypeName() {
return returnTypeName;
}
@Override
public List<String> getParameterTypeNames() {
return parameterTypeNames;
}
@Override
public String getFunctionName() {
return functionName;
}
@Override
public String getDisplayName() {
return displayName;
}
@Override
public boolean isDimension() {
return isDimension;
}
@Override
public int getOrdinal() {
return ordinal;
}
@@ -76,7 +68,6 @@ public class FunctionDTOImpl implements FunctionDTO {
return Integer.compare(this.getOrdinal(), f.getOrdinal());
}
@Override
public String toString() {
return (isDimension() ? "Dimension " : "Function ") + sourceTypeName + "." + functionName + "(" + parametersAsString() + ") : " + returnTypeName;
}
@@ -114,7 +105,7 @@ public class FunctionDTOImpl implements FunctionDTO {
return false;
if (getClass() != obj.getClass())
return false;
FunctionDTOImpl other = (FunctionDTOImpl) obj;
FunctionDTO other = (FunctionDTO) obj;
if (functionName == null) {
if (other.functionName != null)
return false;
@@ -26,6 +26,11 @@ public class LocalizedTypeDTO implements Serializable {
public String getDisplayName() {
return displayName;
}
@Override
public String toString() {
return getTypeName() + "[" + getDisplayName() + "]";
}
@Override
public int hashCode() {
@@ -7,9 +7,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
public class QueryDefinitionDTOImpl implements QueryDefinitionDTO {
private static final long serialVersionUID = -6438771277564908352L;
@@ -96,10 +96,6 @@ public class TestDataRetrieverChainCreation {
chainBuilder.getCurrentRetrievedDataType();
} catch (IllegalStateException e) {
}
try {
chainBuilder.getCurrentRetrieverLevel();
} catch (IllegalStateException e) {
}
try {
chainBuilder.setFilter(null);
} catch (IllegalStateException e) {
@@ -81,7 +81,8 @@ public class TestDataRetrieverChainDefinitionRegistry {
public void testRemoveDataRetrieverChainDefinition() {
Class<Collection<Test_Regatta>> dataSourceType = (Class<Collection<Test_Regatta>>)(Class<?>) Collection.class;
dataRetrieverChainDefinitionRegistry.unregister(legRetrieverChainDefinition);
assertThat(dataRetrieverChainDefinitionRegistry.unregister(legRetrieverChainDefinition), is(true));
assertThat(dataRetrieverChainDefinitionRegistry.unregister(legRetrieverChainDefinition), is(false));
Collection<DataRetrieverChainDefinition<Collection<Test_Regatta>, Test_HasLegOfCompetitorContext>> expectedEmptyDataRetrieverChainDefinitions = new HashSet<>();
assertThat(dataRetrieverChainDefinitionRegistry.get(dataSourceType, Test_HasLegOfCompetitorContext.class), is(expectedEmptyDataRetrieverChainDefinitions));
}
@@ -91,7 +92,7 @@ public class TestDataRetrieverChainDefinitionRegistry {
public void testAddingDataRetrieverChainDefinitionTwice() {
Class<Collection<Test_Regatta>> dataSourceType = (Class<Collection<Test_Regatta>>)(Class<?>) Collection.class;
dataRetrieverChainDefinitionRegistry.register(legRetrieverChainDefinition);
assertThat(dataRetrieverChainDefinitionRegistry.register(legRetrieverChainDefinition), is(false));
Collection<DataRetrieverChainDefinition<Collection<Test_Regatta>, Test_HasLegOfCompetitorContext>> expectedDataRetrieverChainDefinitions = new HashSet<>();
expectedDataRetrieverChainDefinitions.add(legRetrieverChainDefinition);
assertThat(dataRetrieverChainDefinitionRegistry.get(dataSourceType, Test_HasLegOfCompetitorContext.class), is(expectedDataRetrieverChainDefinitions));
@@ -25,8 +25,8 @@ import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.impl.functions.SimpleParameterizedFunction;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.test.functions.registry.test_classes.Test_Boat;
import com.sap.sse.datamining.test.functions.registry.test_classes.Test_Competitor;
import com.sap.sse.datamining.test.functions.registry.test_classes.Test_Named;
@@ -41,9 +41,9 @@ import com.sap.sse.datamining.impl.criterias.AbstractFilterCriterion;
import com.sap.sse.datamining.impl.functions.SimpleParameterizedFunction;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.QueryResultState;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.data.QueryResultState;
import com.sap.sse.datamining.shared.data.Unit;
import com.sap.sse.datamining.shared.impl.AdditionalResultDataImpl;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
import com.sap.sse.datamining.shared.impl.QueryResultImpl;
@@ -11,7 +11,7 @@ import org.junit.Before;
import org.junit.Test;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
import com.sap.sse.datamining.test.functions.test_classes.ContainerElement;
import com.sap.sse.datamining.test.functions.test_classes.ContainerElementImpl;
import com.sap.sse.datamining.test.functions.test_classes.MarkedContainer;
@@ -12,8 +12,7 @@ import org.junit.Before;
import org.junit.Test;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTOImpl;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.test.functions.test_classes.SimpleClassWithMarkedMethods;
import com.sap.sse.datamining.test.functions.test_classes.Test_ExternalLibraryClass;
import com.sap.sse.datamining.test.util.FunctionTestsUtil;
@@ -47,7 +46,7 @@ public class TestFunctionDTOConstruction {
assertThat(FunctionTestsUtil.getFunctionDTOFactory().createFunctionDTO(dimension, stringMessages, Locale.GERMAN), is(expectedDimensionDTO));
}
public FunctionDTOImpl createExpectedDimensionDTO() {
public FunctionDTO createExpectedDimensionDTO() {
String functionName = dimensionMethod.getName();
String sourceTypeName = dimensionMethod.getDeclaringClass().getSimpleName();
String returnTypeName = dimensionMethod.getReturnType().getSimpleName();
@@ -57,7 +56,7 @@ public class TestFunctionDTOConstruction {
boolean isDimension = true;
int ordinal = 0;
return new FunctionDTOImpl(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
return new FunctionDTO(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
}
@Test
@@ -79,7 +78,7 @@ public class TestFunctionDTOConstruction {
boolean isDimension = false;
int ordinal = 0;
return new FunctionDTOImpl(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
return new FunctionDTO(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
}
@Test
@@ -101,7 +100,7 @@ public class TestFunctionDTOConstruction {
boolean isDimension = false;
int ordinal = 0;
return new FunctionDTOImpl(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
return new FunctionDTO(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
}
@Test
@@ -124,7 +123,7 @@ public class TestFunctionDTOConstruction {
boolean isDimension = false;
int ordinal = 0;
return new FunctionDTOImpl(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
return new FunctionDTO(isDimension, functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, ordinal);
}
@Test
@@ -17,7 +17,7 @@ import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.impl.SimpleDataRetrieverChainDefinition;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.datamining.test.functions.registry.test_classes.Test_Named;
import com.sap.sse.datamining.test.functions.registry.test_classes.Test_Regatta;
import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasLegOfCompetitorContext;
@@ -46,8 +46,8 @@ public class TestFunctionManagerAsFunctionRegistry {
@Test
public void testRegistration() throws NoSuchMethodException, SecurityException {
OpenFunctionManager registry = new OpenFunctionManager();
registry.registerAllClasses(internalClassesToScan);
registry.registerAllWithExternalFunctionPolicy(externalClassesToScan);
assertThat(registry.registerAllClasses(internalClassesToScan), is(true));
assertThat(registry.registerAllWithExternalFunctionPolicy(externalClassesToScan), is(true));
Collection<Function<?>> expectedDimensions = new HashSet<>();
expectedDimensions.addAll(expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegOfCompetitorContext.class));
@@ -61,6 +61,16 @@ public class TestFunctionManagerAsFunctionRegistry {
assertThat(registry.getExternalFunctions(), is(expectedExternalFunctions));
}
@Test
public void testMultipleRegistrationAndUnregistrationOfTheSameClasses() {
OpenFunctionManager registry = new OpenFunctionManager();
assertThat(registry.registerAllClasses(internalClassesToScan), is(true));
assertThat(registry.registerAllClasses(internalClassesToScan), is(false));
assertThat(registry.unregisterAllFunctionsOf(internalClassesToScan), is(true));
assertThat(registry.unregisterAllFunctionsOf(internalClassesToScan), is(false));
}
@Test
public void testUnregistration() {
OpenFunctionManager registry = new OpenFunctionManager();
@@ -73,7 +83,7 @@ public class TestFunctionManagerAsFunctionRegistry {
Set<Class<?>> classesToUnregister = new HashSet<>();
classesToUnregister.add(Test_HasLegOfCompetitorContext.class);
registry.unregisterAllFunctionsOf(classesToUnregister);
assertThat(registry.unregisterAllFunctionsOf(classesToUnregister), is(true));
expectedDimensions = expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasRaceContext.class);
assertThat(registry.getDimensions(), is(expectedDimensions));
@@ -81,7 +91,7 @@ public class TestFunctionManagerAsFunctionRegistry {
registry.registerAllClasses(internalClassesToScan);
classesToUnregister = new HashSet<>();
classesToUnregister.add(Test_HasRaceContext.class);
registry.unregisterAllFunctionsOf(classesToUnregister);
assertThat(registry.unregisterAllFunctionsOf(classesToUnregister), is(true));
expectedDimensions = expectedFunctionRegistryUtil.getExpectedDimensionsFor(Test_HasLegOfCompetitorContext.class);
assertThat(registry.getDimensions(), is(expectedDimensions));
@@ -48,12 +48,14 @@ public class TestI18N {
compoundStringMessages.get(Locale.ENGLISH, SIMPLE_TEST_MESSAGE_KEY);
fail("There shouldn't be a string message in an empty compound string messages");
} catch (MissingResourceException e) { }
compoundStringMessages.addStringMessages(testStringMessages);
assertThat(compoundStringMessages.addStringMessages(testStringMessages), is(true));
assertThat(compoundStringMessages.addStringMessages(testStringMessages), is(false));
assertThat(testStringMessages.get(Locale.ENGLISH, SIMPLE_TEST_MESSAGE_KEY), is("English"));
assertThat(testStringMessages.get(Locale.GERMAN, SIMPLE_TEST_MESSAGE_KEY), is("Deutsch"));
compoundStringMessages.removeStringMessages(testStringMessages);
assertThat(compoundStringMessages.removeStringMessages(testStringMessages), is(true));
assertThat(compoundStringMessages.removeStringMessages(testStringMessages), is(false));
try {
compoundStringMessages.get(Locale.ENGLISH, SIMPLE_TEST_MESSAGE_KEY);
fail("There shouldn't be a string message in an empty compound string messages");
@@ -1,7 +1,7 @@
package com.sap.sse.datamining.test.functions.registry.test_classes;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Statistic;
import com.sap.sse.datamining.shared.data.Unit;
public interface Test_Leg {
@@ -1,7 +1,7 @@
package com.sap.sse.datamining.test.functions.test_classes;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Statistic;
import com.sap.sse.datamining.shared.data.Unit;
public interface DataTypeInterface {
@@ -4,7 +4,7 @@ import java.util.Locale;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.shared.AdditionalResultData;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
import com.sap.sse.i18n.ResourceBundleStringMessages;
/**
@@ -1,6 +1,9 @@
package com.sap.sse.datamining;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
@@ -8,9 +11,9 @@ import java.util.concurrent.ExecutorService;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
@@ -22,6 +25,8 @@ public interface DataMiningServer {
public FunctionProvider getFunctionProvider();
public Date getComponentsChangedTimepoint();
public Iterable<Function<?>> getAllStatistics();
public Iterable<Function<?>> getFunctionsFor(Class<?> sourceType);
@@ -53,7 +58,7 @@ public interface DataMiningServer {
public <DataSourceType, DataType, ResultType> QueryDefinition<DataSourceType, DataType, ResultType> getQueryDefinitionForDTO(QueryDefinitionDTO queryDefinitionDTO);
public <DataSourceType> Query<Set<Object>> createDimensionValuesQuery(DataRetrieverChainDefinition<DataSourceType, ?> dataRetrieverChainDefinition, int retrieverLevel,
Iterable<Function<?>> dimensions, Locale locale);
Iterable<Function<?>> dimensions, Map<Integer, Map<Function<?>, Collection<?>>> filterSelection, Locale locale);
public <DataSourceType, ResultType> Query<ResultType> createQuery(QueryDefinition<DataSourceType, ?, ResultType> queryDefinition);
@@ -32,8 +32,7 @@ public interface DataRetrieverChainBuilder<DataSourceType> {
public Class<?> getCurrentRetrievedDataType();
/**
* @throws IllegalStateException if {@link #stepFurther()} has not yet been called.
* @return The current retriever level.
* @return The current retriever level or <code>-1</code> if {@link #stepFurther()} has not yet been called.
*/
public int getCurrentRetrieverLevel();
@@ -3,7 +3,7 @@ package com.sap.sse.datamining;
public interface DataRetrieverChainDefinitionRegistry extends DataRetrieverChainDefinitionProvider {
public void register(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition);
public void unregister(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition);
public boolean register(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition);
public boolean unregister(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition);
}
@@ -1,6 +1,6 @@
package com.sap.sse.datamining;
import com.sap.sse.datamining.shared.QueryResultState;
import com.sap.sse.datamining.shared.data.QueryResultState;
public enum QueryState {
@@ -7,8 +7,7 @@ import java.util.Locale;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Dimension;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTOImpl;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public class FunctionDTOFactory {
@@ -35,7 +34,7 @@ public class FunctionDTOFactory {
String sourceTypeName = function.getDeclaringType().getSimpleName();
String returnTypeName = function.getReturnType().getSimpleName();
List<String> parameterTypeNames = getParameterTypeNames(function);
return new FunctionDTOImpl(function.isDimension(), functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, function.getOrdinal());
return new FunctionDTO(function.isDimension(), functionName, sourceTypeName, returnTypeName, parameterTypeNames, displayName, function.getOrdinal());
}
private List<String> getParameterTypeNames(Function<?> function) {
@@ -118,9 +118,9 @@ public class QueryFactory {
}
public <DataSource> Query<Set<Object>> createDimensionValuesQuery(DataSource dataSource,
DataRetrieverChainDefinition<DataSource, ?> dataRetrieverChainDefinition, int retrieverLevel,
Iterable<Function<?>> dimensions, Locale locale,
ResourceBundleStringMessages stringMessages, ExecutorService executor) {
final DataRetrieverChainDefinition<DataSource, ?> dataRetrieverChainDefinition, final int retrieverLevel,
final Iterable<Function<?>> dimensions, final Map<Integer, Map<Function<?>, Collection<?>>> filterSelection, final Locale locale,
final ResourceBundleStringMessages stringMessages, final ExecutorService executor) {
return new ProcessorQuery<Set<Object>, DataSource>(dataSource, stringMessages, locale, new SimpleAdditionalQueryData(QueryType.DIMENSION_VALUES, dataRetrieverChainDefinition.getID())) {
@Override
protected Processor<DataSource, ?> createFirstProcessor() {
@@ -128,10 +128,14 @@ public class QueryFactory {
Processor<GroupedDataEntry<Object>, Map<GroupKey, Set<Object>>> valueCollector = processorFactory.createGroupedDataCollectingAsSetProcessor(/*query*/ this);
Map<Integer, FilterCriterion<?>> criteriaMappedByRetrieverLevel = createFilterCriteria(filterSelection);
DataRetrieverChainBuilder<DataSource> chainBuilder = dataRetrieverChainDefinition.startBuilding(executor);
chainBuilder.stepFurther(); //Initialization
for (int level = 0; level < retrieverLevel; level++) {
while (chainBuilder.getCurrentRetrieverLevel() < retrieverLevel) {
chainBuilder.stepFurther();
if (criteriaMappedByRetrieverLevel.containsKey(chainBuilder.getCurrentRetrieverLevel())) {
chainBuilder.setFilter(criteriaMappedByRetrieverLevel.get(chainBuilder.getCurrentRetrieverLevel()));
}
}
for (Processor<?, ?> resultReceiver : processorFactory.createGroupingExtractorsForDimensions(
chainBuilder.getCurrentRetrievedDataType(), valueCollector, getParameterProvidersFor(dimensions, stringMessages, locale), stringMessages, locale)) {
@@ -3,7 +3,7 @@ package com.sap.sse.datamining.functions;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public interface Function<ReturnType> {
@@ -3,7 +3,7 @@ package com.sap.sse.datamining.functions;
import java.util.Collection;
import com.sap.sse.datamining.DataRetrieverChainDefinition;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public interface FunctionProvider {
@@ -2,9 +2,9 @@ package com.sap.sse.datamining.functions;
public interface FunctionRegistry {
public void registerAllClasses(Iterable<Class<?>> classesToScan);
public void registerAllWithExternalFunctionPolicy(Iterable<Class<?>> externalClassesToScan);
public boolean registerAllClasses(Iterable<Class<?>> classesToScan);
public boolean registerAllWithExternalFunctionPolicy(Iterable<Class<?>> externalClassesToScan);
public void unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister);
public boolean unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister);
}
@@ -2,6 +2,7 @@ package com.sap.sse.datamining.impl;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -23,9 +24,9 @@ import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionProvider;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.shared.DataMiningSession;
import com.sap.sse.datamining.shared.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.dto.QueryDefinitionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
import com.sap.sse.i18n.impl.CompoundResourceBundleStringMessages;
@@ -33,6 +34,7 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
private final CompoundResourceBundleStringMessages stringMessages;
private final ExecutorService executorService;
private Date componentsChangedTimepoint;
private final QueryFactory queryFactory;
private final DataMiningQueryManager dataMiningQueryManager;
@@ -46,6 +48,7 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
public DataMiningServerImpl(ExecutorService executorService, FunctionRegistry functionRegistry, FunctionProvider functionProvider, DataRetrieverChainDefinitionRegistry dataRetrieverChainDefinitionRegistry) {
this.stringMessages = new CompoundResourceBundleStringMessages();
this.executorService = executorService;
componentsChangedTimepoint = new Date();
this.queryFactory = new QueryFactory();
dataMiningQueryManager = new StrategyPerQueryTypeManager();
this.functionRegistry = functionRegistry;
@@ -53,6 +56,15 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
dataSourceProviderMappedByDataSourceType = new HashMap<>();
this.dataRetrieverChainDefinitionRegistry = dataRetrieverChainDefinitionRegistry;
}
@Override
public Date getComponentsChangedTimepoint() {
return componentsChangedTimepoint;
}
private void updateComponentsChangedTimepoint() {
componentsChangedTimepoint = new Date();
}
@Override
public ExecutorService getExecutorService() {
@@ -66,12 +78,18 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
@Override
public void addStringMessages(ResourceBundleStringMessages stringMessages) {
this.stringMessages.addStringMessages(stringMessages);
boolean componentsChanged = this.stringMessages.addStringMessages(stringMessages);
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
public void removeStringMessages(ResourceBundleStringMessages stringMessages) {
this.stringMessages.removeStringMessages(stringMessages);
boolean componentsChanged = this.stringMessages.removeStringMessages(stringMessages);
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
@@ -81,17 +99,26 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
@Override
public void registerAllClasses(Iterable<Class<?>> classesToScan) {
functionRegistry.registerAllClasses(classesToScan);
boolean componentsChanged = functionRegistry.registerAllClasses(classesToScan);
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
public void registerAllWithExternalFunctionPolicy(Iterable<Class<?>> externalClassesToScan) {
functionRegistry.registerAllWithExternalFunctionPolicy(externalClassesToScan);
boolean componentsChanged = functionRegistry.registerAllWithExternalFunctionPolicy(externalClassesToScan);
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
public void unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister) {
functionRegistry.unregisterAllFunctionsOf(classesToUnregister);
boolean componentsChanged = functionRegistry.unregisterAllFunctionsOf(classesToUnregister);
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
@@ -132,11 +159,15 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
@Override
public void setDataSourceProvider(DataSourceProvider<?> dataSourceProvider) {
dataSourceProviderMappedByDataSourceType.put(dataSourceProvider.getDataSourceType(), dataSourceProvider);
updateComponentsChangedTimepoint();
}
@Override
public void removeDataSourceProvider(DataSourceProvider<?> dataSourceProvider) {
dataSourceProviderMappedByDataSourceType.remove(dataSourceProvider.getDataSourceType());
boolean componentsChanged = dataSourceProviderMappedByDataSourceType.remove(dataSourceProvider.getDataSourceType()) != null;
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
@@ -146,12 +177,18 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
@Override
public void registerDataRetrieverChainDefinition(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
dataRetrieverChainDefinitionRegistry.register(dataRetrieverChainDefinition);
boolean componentsChanged = dataRetrieverChainDefinitionRegistry.register(dataRetrieverChainDefinition);
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
public void unregisterDataRetrieverChainDefinition(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
dataRetrieverChainDefinitionRegistry.unregister(dataRetrieverChainDefinition);
boolean componentsChanged = dataRetrieverChainDefinitionRegistry.unregister(dataRetrieverChainDefinition);
if (componentsChanged) {
updateComponentsChangedTimepoint();
}
}
@Override
@@ -218,9 +255,9 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
@Override
public <DataSourceType> Query<Set<Object>> createDimensionValuesQuery(DataRetrieverChainDefinition<DataSourceType, ?> dataRetrieverChainDefinition, int retrieverLevel,
Iterable<Function<?>> dimensions, Locale locale) {
Iterable<Function<?>> dimensions, Map<Integer, Map<Function<?>, Collection<?>>> filterSelection, Locale locale) {
DataSourceProvider<DataSourceType> dataSourceProvider = getDataSourceProviderFor(dataRetrieverChainDefinition.getDataSourceType());
return queryFactory.createDimensionValuesQuery(dataSourceProvider.getDataSource(), dataRetrieverChainDefinition, retrieverLevel, dimensions, locale, getStringMessages(), getExecutorService());
return queryFactory.createDimensionValuesQuery(dataSourceProvider.getDataSource(), dataRetrieverChainDefinition, retrieverLevel, dimensions, filterSelection, locale, getStringMessages(), getExecutorService());
}
@SuppressWarnings("unchecked")
@@ -23,7 +23,7 @@ import com.sap.sse.datamining.impl.components.OverwritingResultDataBuilder;
import com.sap.sse.datamining.shared.AdditionalResultData;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.QueryResult;
import com.sap.sse.datamining.shared.QueryResultState;
import com.sap.sse.datamining.shared.data.QueryResultState;
import com.sap.sse.datamining.shared.impl.NullAdditionalResultData;
import com.sap.sse.datamining.shared.impl.QueryResultImpl;
import com.sap.sse.i18n.ResourceBundleStringMessages;
@@ -110,10 +110,6 @@ public class SimpleDataRetrieverChainBuilder<DataSourceType> implements DataRetr
@Override
public int getCurrentRetrieverLevel() {
if (!hasBeenInitialized()) {
throw new IllegalStateException("The builder hasn't been initialized");
}
return currentRetrieverTypeIndex;
}
@@ -23,10 +23,15 @@ public class SimpleDataRetrieverChainDefinitionRegistry implements DataRetriever
}
@Override
public void register(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
public boolean register(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
if (chainDefinitionsMappedByID.containsKey(dataRetrieverChainDefinition.getID())) {
return false;
}
registerToBySourceTypeMap(dataRetrieverChainDefinition);
registerToByDataTypeMap(dataRetrieverChainDefinition);
chainDefinitionsMappedByID.put(dataRetrieverChainDefinition.getID(), dataRetrieverChainDefinition);
return true;
}
private void registerToBySourceTypeMap(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
@@ -45,10 +50,10 @@ public class SimpleDataRetrieverChainDefinitionRegistry implements DataRetriever
}
@Override
public void unregister(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
public boolean unregister(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
unregisterFromBySourceTypeMap(dataRetrieverChainDefinition);
unregisterFromByDataTypeMap(dataRetrieverChainDefinition);
chainDefinitionsMappedByID.remove(dataRetrieverChainDefinition.getID());
return chainDefinitionsMappedByID.remove(dataRetrieverChainDefinition.getID()) != null;
}
private void unregisterFromBySourceTypeMap(DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition) {
@@ -5,7 +5,7 @@ import java.util.Locale;
import com.sap.sse.datamining.AdditionalResultDataBuilder;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.shared.AdditionalResultData;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
import com.sap.sse.datamining.shared.impl.AdditionalResultDataImpl;
import com.sap.sse.i18n.ResourceBundleStringMessages;
@@ -11,8 +11,8 @@ import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.functions.ParameterizedFunction;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
import com.sap.sse.i18n.ResourceBundleStringMessages;
/**
@@ -9,7 +9,7 @@ import com.sap.sse.datamining.AdditionalResultDataBuilder;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.shared.GroupKey;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
public class ParallelGroupedDataCountAggregationProcessor extends
AbstractParallelStoringAggregationProcessor<GroupedDataEntry<?>, Map<GroupKey, Double>> {
@@ -1,6 +1,6 @@
package com.sap.sse.datamining.impl.functions;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
public class AdditionalMethodWrappingFunctionData {
@@ -7,7 +7,7 @@ import java.util.Locale;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.data.Unit;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public class ConcatenatingCompoundFunction<ReturnType> extends AbstractFunction<ReturnType> {
@@ -27,7 +27,7 @@ import com.sap.sse.datamining.impl.functions.criterias.MethodIsValidDimensionFil
import com.sap.sse.datamining.impl.functions.criterias.MethodIsValidExternalFunctionFilterCriterion;
import com.sap.sse.datamining.impl.functions.criterias.MethodIsValidStatisticFilterCriterion;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public class FunctionManager implements FunctionRegistry, FunctionProvider {
@@ -86,97 +86,110 @@ public class FunctionManager implements FunctionRegistry, FunctionProvider {
}
@Override
public void registerAllClasses(Iterable<Class<?>> internalClassesToScan) {
public boolean registerAllClasses(Iterable<Class<?>> internalClassesToScan) {
boolean functionsHaveBeenRegistered = false;
for (Class<?> internalClass : internalClassesToScan) {
scanInternalClass(internalClass);
boolean functionsOfClassHaveBeenRegistered = scanInternalClass(internalClass);
functionsHaveBeenRegistered = functionsHaveBeenRegistered ? true : functionsOfClassHaveBeenRegistered;
}
return functionsHaveBeenRegistered;
}
private void scanInternalClass(Class<?> internalClass) {
scanInternalClass(internalClass, new ArrayList<Function<?>>(), true);
private boolean scanInternalClass(Class<?> internalClass) {
return scanInternalClass(internalClass, new ArrayList<Function<?>>(), true);
}
private void scanInternalClass(Class<?> internalClass, List<Function<?>> previousFunctions, boolean scanForStatistics) {
private boolean scanInternalClass(Class<?> internalClass, List<Function<?>> previousFunctions, boolean scanForStatistics) {
boolean functionsHaveBeenRegistered = false;
for (Method method : internalClass.getMethods()) {
boolean functionHasBeenRegistered = false;
if (isValidDimension.matches(method) || (scanForStatistics && isValidStatistic.matches(method) )) {
registerFunction(previousFunctions, method);
continue;
}
if (isValidConnector.matches(method)) {
handleConnectorMethod(method, previousFunctions, scanForStatistics);
functionHasBeenRegistered = registerFunction(previousFunctions, method);
} else if (isValidConnector.matches(method)) {
functionHasBeenRegistered = handleConnectorMethod(method, previousFunctions, scanForStatistics);
}
functionsHaveBeenRegistered = functionsHaveBeenRegistered ? true : functionHasBeenRegistered;
}
return functionsHaveBeenRegistered;
}
private void registerFunction(List<Function<?>> previousFunctions, Method method) {
private boolean registerFunction(List<Function<?>> previousFunctions, Method method) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
if (!previousFunctions.isEmpty()) {
function = functionFactory.createCompoundFunction(previousFunctions, function);
}
if (function.isDimension()) {
addDimension(function);
return addDimension(function);
} else {
addStatistic(function);
return addStatistic(function);
}
}
private void addDimension(Function<?> dimension) {
private boolean addDimension(Function<?> dimension) {
Class<?> declaringType = dimension.getDeclaringType();
if (!dimensions.containsKey(declaringType)) {
dimensions.put(declaringType, new HashSet<Function<?>>());
}
dimensions.get(declaringType).add(dimension);
return dimensions.get(declaringType).add(dimension);
}
private void addStatistic(Function<?> statistic) {
private boolean addStatistic(Function<?> statistic) {
Class<?> declaringType = statistic.getDeclaringType();
if (!statistics.containsKey(declaringType)) {
statistics.put(declaringType, new HashSet<Function<?>>());
}
statistics.get(declaringType).add(statistic);
return statistics.get(declaringType).add(statistic);
}
private void handleConnectorMethod(Method method, List<Function<?>> previousFunctions, boolean scanForStatistics) {
private boolean handleConnectorMethod(Method method, List<Function<?>> previousFunctions, boolean scanForStatistics) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
Class<?> returnType = method.getReturnType();
List<Function<?>> previousFunctionsClone = new ArrayList<>(previousFunctions);
previousFunctionsClone.add(function);
scanInternalClass(returnType, previousFunctionsClone, !scanForStatistics ? false : method.getAnnotation(Connector.class).scanForStatistics());
return scanInternalClass(returnType, previousFunctionsClone, !scanForStatistics ? false : method.getAnnotation(Connector.class).scanForStatistics());
}
@Override
public void registerAllWithExternalFunctionPolicy(Iterable<Class<?>> externalClassesToScan) {
public boolean registerAllWithExternalFunctionPolicy(Iterable<Class<?>> externalClassesToScan) {
boolean functionsHaveBeenRegistered = false;
for (Class<?> externalClass : externalClassesToScan) {
for (Method method : externalClass.getMethods()) {
if (isValidExternalFunction.matches(method)) {
Function<?> function = functionFactory.createMethodWrappingFunction(method);
addExternalFunction(function);
boolean functionsOfClassHaveBeenRegistered = addExternalFunction(function);
functionsHaveBeenRegistered = functionsHaveBeenRegistered ? true : functionsOfClassHaveBeenRegistered;
}
}
}
return functionsHaveBeenRegistered;
}
private void addExternalFunction(Function<?> function) {
private boolean addExternalFunction(Function<?> function) {
Class<?> declaringType = function.getDeclaringType();
if (!externalFunctions.containsKey(declaringType)) {
externalFunctions.put(declaringType, new HashSet<Function<?>>());
}
externalFunctions.get(declaringType).add(function);
return externalFunctions.get(declaringType).add(function);
}
@Override
public void unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister) {
public boolean unregisterAllFunctionsOf(Iterable<Class<?>> classesToUnregister) {
boolean functionsHaveBeenUnregistered = false;
for (Class<?> classToUnregister : classesToUnregister) {
unregisterAllFunctionsOf(classToUnregister);
boolean functionsOfClassHaveBeenUnregistered = unregisterAllFunctionsOf(classToUnregister);
functionsHaveBeenUnregistered = functionsHaveBeenUnregistered ? true : functionsOfClassHaveBeenUnregistered;
}
return functionsHaveBeenUnregistered;
}
private void unregisterAllFunctionsOf(Class<?> classToUnregister) {
private boolean unregisterAllFunctionsOf(Class<?> classToUnregister) {
boolean functionsHaveBeenUnregistered = false;
for (Map<Class<?>, Set<Function<?>>> functionMap : functionMaps) {
functionMap.remove(classToUnregister);
boolean functionsOfClassHaveBeenUnregistered = functionMap.remove(classToUnregister) != null;
functionsHaveBeenUnregistered = functionsHaveBeenUnregistered ? true : functionsOfClassHaveBeenUnregistered;
}
return functionsHaveBeenUnregistered;
}
private Collection<Function<?>> getAllFunctionsOf(Class<?> declaringType) {
@@ -301,7 +314,11 @@ public class FunctionManager implements FunctionRegistry, FunctionProvider {
logThatMoreThanOneFunctionMatchedDTO(functionDTO, functionsMatchingDTO);
}
return getFunctionToReturn(functionsMatchingDTO);
Function<?> function = getFunctionToReturn(functionsMatchingDTO);
if (function == null) {
LOGGER.log(Level.WARNING, "No function found for the DTO: " + functionDTO);
}
return function;
}
private Collection<Function<?>> getFunctionsForDTO(FunctionDTO functionDTO) {
@@ -7,10 +7,10 @@ import java.util.Locale;
import java.util.logging.Level;
import com.sap.sse.datamining.functions.ParameterProvider;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Dimension;
import com.sap.sse.datamining.shared.annotations.Statistic;
import com.sap.sse.datamining.shared.data.Unit;
import com.sap.sse.i18n.ResourceBundleStringMessages;
public class MethodWrappingFunction<ReturnType> extends AbstractFunction<ReturnType> {
@@ -2,7 +2,7 @@ package com.sap.sse.datamining.impl.functions.criterias;
import com.sap.sse.datamining.factories.FunctionDTOFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
public class FunctionMatchesDTOFilterCriterion extends AbstractFunctionFilterCriterion {
@@ -29,12 +29,12 @@ public class CompoundResourceBundleStringMessages implements ResourceBundleStrin
this.stringMessages = new HashSet<>(stringMessages);
}
public void addStringMessages(ResourceBundleStringMessages stringMessages) {
this.stringMessages.add(stringMessages);
public boolean addStringMessages(ResourceBundleStringMessages stringMessages) {
return this.stringMessages.add(stringMessages);
}
public void removeStringMessages(ResourceBundleStringMessages stringMessages) {
this.stringMessages.remove(stringMessages);
public boolean removeStringMessages(ResourceBundleStringMessages stringMessages) {
return this.stringMessages.remove(stringMessages);
}
@Override