Merge branch 'master' into ubilabs--rcapp--develop

This commit is contained in:
Peter Siegmund committed 2015-04-30 14:34:59 +02:00
commit 0620a83ea9
97 files changed
+5042 -4354

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.
@@ -34,7 +34,8 @@ public class SharingButtons extends Composite {
mail.setHref(mailtoLink.buildString().replace("+", "%20"));
UrlBuilder twitterLink = new UrlBuilder().setProtocol("https").setHost("twitter.com").setPath("intent/tweet").setParameter("text", shortText).setParameter("url", Window.Location.getHref()).setParameter("short_url_length", "8");
twitter.setHref(twitterLink.buildString());
UrlBuilder facebookLink = new UrlBuilder().setProtocol("https").setHost("www.facebook.com").setPath("dialog/feed").setParameter("display", "page").setParameter("caption", shortText).setParameter("link", Window.Location.getHref()).setParameter("redirect_uri", Window.Location.getHref());
UrlBuilder facebookLink = new UrlBuilder().setProtocol("https").setHost("www.facebook.com")
.setPath("sharer/sharer.php").setParameter("u", Window.Location.getHref());
facebook.setHref(facebookLink.buildString());
}
}
@@ -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)}
@@ -56,9 +56,8 @@
<!-- Specify the app entry point class. -->
<!-- Specify the paths for translatable code -->
<extend-property name="locale" values="en" />
<extend-property name="locale" values="de" />
<extend-property name="locale" values="cn" />
<extend-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 -->
@@ -31,10 +31,9 @@
<entry-point class='com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint'/>
<!-- Specify the paths for translatable code -->
<extend-property name="locale" values="en" />
<extend-property name="locale" values="de"/>
<extend-property name="locale" values="ru"/>
<extend-property name="locale" values="cn"/>
<extend-property name="locale" values="en,de,cn,ru" />
<extend-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
-2
View File
@@ -172,8 +172,6 @@ Abstract processors have the following abstract methods:
An useful method for concrete processors is the protected method `createInvalidResult`, that returns an instruction, that won't be passed to the `ExecutorService`. This can be used to stop the processing of a specific input element (for example to filter the data).
**TODO:** *Describe the usage of prioritized instructions, with the `DataMiningExecutorService`*
There are useful implementations of the abstract processors, that are more specialized. These special processors implement the creation of instructions and the setting of the additional data for their special case.
#### Retrieval Processor