From db1d39b4cb2d39b9f041fc26d0493e4276639af1 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Mon, 8 Feb 2016 13:54:54 +0200 Subject: Provide simple clean up for DataProvider on remove and UI detach Change-Id: Ib21fbb5a254814725400b31ccaf023e4b7e13d1c --- .../data/typed/AbstractDataSource.java | 4 +- .../communication/data/typed/DataProvider.java | 48 +++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/server/src/com/vaadin/server/communication/data/typed/AbstractDataSource.java b/server/src/com/vaadin/server/communication/data/typed/AbstractDataSource.java index bf16b47aa5..98f68ed536 100644 --- a/server/src/com/vaadin/server/communication/data/typed/AbstractDataSource.java +++ b/server/src/com/vaadin/server/communication/data/typed/AbstractDataSource.java @@ -30,7 +30,9 @@ public abstract class AbstractDataSource implements DataSource { @Override public void addDataChangeHandler(DataChangeHandler handler) { - handlers.add(handler); + if (handler != null) { + handlers.add(handler); + } } @Override diff --git a/server/src/com/vaadin/server/communication/data/typed/DataProvider.java b/server/src/com/vaadin/server/communication/data/typed/DataProvider.java index 7cba66aa64..2c45c52ed5 100644 --- a/server/src/com/vaadin/server/communication/data/typed/DataProvider.java +++ b/server/src/com/vaadin/server/communication/data/typed/DataProvider.java @@ -22,6 +22,7 @@ import java.util.LinkedHashSet; import java.util.Set; import com.vaadin.server.AbstractExtension; +import com.vaadin.server.ClientConnector; import com.vaadin.server.communication.data.typed.DataSource.DataChangeHandler; import com.vaadin.shared.data.DataProviderClientRpc; import com.vaadin.shared.data.DataProviderConstants; @@ -178,13 +179,42 @@ public abstract class DataProvider extends AbstractExtension { protected DataProviderClientRpc rpc; protected DataSource dataSource; + private DataChangeHandler dataChangeHandler; + private DetachListener detachListener; protected DataProvider(DataSource dataSource) { addDataGenerator(handler); this.dataSource = dataSource; rpc = getRpcProxy(DataProviderClientRpc.class); registerRpc(createRpc()); - this.dataSource.addDataChangeHandler(createDataChangeHandler()); + dataChangeHandler = createDataChangeHandler(); + this.dataSource.addDataChangeHandler(dataChangeHandler); + } + + @Override + public void attach() { + super.attach(); + + if (detachListener == null) { + detachListener = new DetachListener() { + + @Override + public void detach(DetachEvent event) { + cleanUp(); + } + }; + getUI().addDetachListener(detachListener); + } + } + + @Override + public void setParent(ClientConnector parent) { + if (getParent() != null && parent == null) { + // Removing from parent, clean up. + cleanUp(); + } + + super.setParent(parent); } /** @@ -266,6 +296,22 @@ public abstract class DataProvider extends AbstractExtension { } } + /** + * Clean up method for removing all listeners attached by the + * {@link DataProvider}. This method is called from {@link #remove()} or + * when the UI gets detached. + */ + protected void cleanUp() { + if (dataSource != null) { + dataSource.removeDataChangeHandler(dataChangeHandler); + dataChangeHandler = null; + } + if (detachListener != null) { + getUI().removeDetachListener(detachListener); + detachListener = null; + } + } + /** * Gets the {@link DataKeyMapper} used by this {@link DataProvider}. * -- cgit v1.2.3