aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTatu Lund <tatu@vaadin.com>2020-08-07 17:39:23 +0300
committerGitHub <noreply@github.com>2020-08-07 17:39:23 +0300
commit415acb75f7ee1eb41a0a7f2fa5ba88b489598224 (patch)
treeeec5f996ee30adc93c7ddc583eada5d335d40151 /server
parent7398f1565ac6e06b871d7f673185fe9faa97e6c5 (diff)
downloadvaadin-framework-415acb75f7ee1eb41a0a7f2fa5ba88b489598224.tar.gz
vaadin-framework-415acb75f7ee1eb41a0a7f2fa5ba88b489598224.zip
Explicitly remove old dataprovider listener when new one is set (#12064)
* Explicitly remove old dataprovider listener when new one is set If not done, this can cause memory leakage * Formatting * Fixed coding style * Take into account further scenarios Component maybe detached permanently and thus data provider listener needs to be remove in detach. Also if this is only momentary remove from layout add back cycle, re-setup is needed in attach, in case it was not already setup before attaching by setDataProvider. * Change super.detach() call order * Added null check to getDataProvider * Setting dataProviderListener to null on detach * Removing listener only if it exists * Fix
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/ui/ComboBox.java42
1 files changed, 35 insertions, 7 deletions
diff --git a/server/src/main/java/com/vaadin/ui/ComboBox.java b/server/src/main/java/com/vaadin/ui/ComboBox.java
index e04cd64241..8f2268b06c 100644
--- a/server/src/main/java/com/vaadin/ui/ComboBox.java
+++ b/server/src/main/java/com/vaadin/ui/ComboBox.java
@@ -245,6 +245,8 @@ public class ComboBox<T> extends AbstractSingleSelect<T>
// Just ignore when neither setDataProvider nor setItems has been called
};
+ private Registration dataProviderListener = null;
+
/**
* Constructs an empty combo box without a caption. The content of the combo
* box can be set with {@link #setDataProvider(DataProvider)} or
@@ -885,6 +887,20 @@ public class ComboBox<T> extends AbstractSingleSelect<T>
// Update icon for ConnectorResource
updateSelectedItemIcon(getValue());
+
+ DataProvider<T, ?> dataProvider = getDataProvider();
+ if (dataProvider != null && dataProviderListener == null) {
+ setupDataProviderListener(dataProvider);
+ }
+ }
+
+ @Override
+ public void detach() {
+ if (dataProviderListener != null) {
+ dataProviderListener.remove();
+ dataProviderListener = null;
+ }
+ super.detach();
}
@Override
@@ -945,7 +961,10 @@ public class ComboBox<T> extends AbstractSingleSelect<T>
@Override
public DataProvider<T, ?> getDataProvider() {
- return internalGetDataProvider();
+ if (this.getDataCommunicator() != null) {
+ return internalGetDataProvider();
+ }
+ return null;
}
@Override
@@ -970,6 +989,11 @@ public class ComboBox<T> extends AbstractSingleSelect<T>
filterSlot = filter -> providerFilterSlot
.accept(convertOrNull.apply(filter));
+ setupDataProviderListener(dataProvider);
+ }
+
+ private <C> void setupDataProviderListener(
+ DataProvider<T, C> dataProvider) {
// This workaround is done to fix issue #11642 for unpaged comboboxes.
// Data sources for on the client need to be updated after data provider
// refreshAll so that serverside selection works even before the
@@ -977,12 +1001,16 @@ public class ComboBox<T> extends AbstractSingleSelect<T>
// is opened. Only done for in-memory data providers for performance
// reasons.
if (dataProvider instanceof InMemoryDataProvider) {
- dataProvider.addDataProviderListener(event -> {
- if ((!(event instanceof DataChangeEvent.DataRefreshEvent))
- && (getPageLength() == 0)) {
- getState().forceDataSourceUpdate = true;
- }
- });
+ if (dataProviderListener != null) {
+ dataProviderListener.remove();
+ }
+ dataProviderListener = dataProvider
+ .addDataProviderListener(event -> {
+ if ((!(event instanceof DataChangeEvent.DataRefreshEvent))
+ && (getPageLength() == 0)) {
+ getState().forceDataSourceUpdate = true;
+ }
+ });
}
}