diff options
4 files changed, 94 insertions, 10 deletions
diff --git a/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java b/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java index b762e3db15..566c7c732f 100644 --- a/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java +++ b/server/src/main/java/com/vaadin/data/provider/DataCommunicator.java @@ -323,13 +323,20 @@ public class DataCommunicator<T> extends AbstractExtension { } Range requestedRows = getPushRows(); + boolean triggerReset = false; if (!requestedRows.isEmpty()) { int offset = requestedRows.getStart(); int limit = requestedRows.length(); @SuppressWarnings({ "rawtypes", "unchecked" }) - Stream<T> rowsToPush = getDataProvider().fetch(new Query(offset, - limit, backEndSorting, inMemorySorting, filter)); + List<T> rowsToPush = (List<T>) getDataProvider() + .fetch(new Query(offset, limit, backEndSorting, + inMemorySorting, filter)) + .collect(Collectors.toList()); + + if (!initial && !reset && rowsToPush.size() == 0) { + triggerReset = true; + } pushData(offset, rowsToPush); } @@ -344,7 +351,7 @@ public class DataCommunicator<T> extends AbstractExtension { } setPushRows(Range.withLength(0, 0)); - reset = false; + reset = triggerReset; updatedData.clear(); } @@ -392,18 +399,17 @@ public class DataCommunicator<T> extends AbstractExtension { * @param data * data objects to send as an iterable */ - protected void pushData(int firstIndex, Stream<T> data) { + protected void pushData(int firstIndex, List<T> data) { JsonArray dataArray = Json.createArray(); int i = 0; - List<T> collected = data.collect(Collectors.toList()); - for (T item : collected) { + for (T item : data) { dataArray.set(i++, getDataObject(item)); } rpc.setData(firstIndex, dataArray); - handler.addActiveData(collected.stream()); - handler.cleanUp(collected.stream()); + handler.addActiveData(data.stream()); + handler.cleanUp(data.stream()); } /** diff --git a/server/src/test/java/com/vaadin/data/provider/ReplaceDataProviderTest.java b/server/src/test/java/com/vaadin/data/provider/ReplaceDataProviderTest.java index f64d6b27c5..fa6f832c32 100644 --- a/server/src/test/java/com/vaadin/data/provider/ReplaceDataProviderTest.java +++ b/server/src/test/java/com/vaadin/data/provider/ReplaceDataProviderTest.java @@ -79,7 +79,7 @@ public class ReplaceDataProviderTest { beans1); dataCommunicator.setDataProvider(dataProvider, null); - dataCommunicator.pushData(1, beans1.stream()); + dataCommunicator.pushData(1, beans1); SOME_BEAN bean1_17 = beans1.get(17); String key1_17 = dataCommunicator.getKeyMapper().key(bean1_17); @@ -90,7 +90,7 @@ public class ReplaceDataProviderTest { dataProvider = new ListDataProvider<>(beans2); dataCommunicator.setDataProvider(dataProvider, null); - dataCommunicator.pushData(1, beans2.stream()); + dataCommunicator.pushData(1, beans2); SOME_BEAN bean2_17 = beans2.get(17); String key2_17 = dataCommunicator.getKeyMapper().key(bean2_17); diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/DataCommunicatorInfiniteLoop.java b/uitest/src/main/java/com/vaadin/tests/components/grid/DataCommunicatorInfiniteLoop.java new file mode 100644 index 0000000000..385a8ef09e --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/DataCommunicatorInfiniteLoop.java @@ -0,0 +1,62 @@ +package com.vaadin.tests.components.grid; + +import java.util.stream.Stream; + +import com.vaadin.data.provider.DataProvider; +import com.vaadin.data.provider.DataProviderListener; +import com.vaadin.data.provider.Query; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.Registration; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; + +public class DataCommunicatorInfiniteLoop extends AbstractTestUI { + + private static class CustomDataProvider + implements DataProvider<String, Void> { + + private boolean sendRealCount = false; + + @Override + public boolean isInMemory() { + return false; + } + + @Override + public int size(Query<String, Void> query) { + if (sendRealCount) { + return 1; + } else { + sendRealCount = true; + return 2; + } + } + + @Override + public Stream<String> fetch(Query<String, Void> query) { + return Stream.of("one item").skip(query.getOffset()); + } + + @Override + public void refreshItem(String item) { + } + + @Override + public void refreshAll() { + } + + @Override + public Registration addDataProviderListener( + DataProviderListener<String> listener) { + return () -> { + }; + } + } + + @Override + protected void setup(VaadinRequest request) { + Grid<String> grid = new Grid<>(new CustomDataProvider()); + grid.addColumn(string -> string); + addComponent(grid); + } +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/DataCommunicatorInfiniteLoopTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/DataCommunicatorInfiniteLoopTest.java new file mode 100644 index 0000000000..b911ad27f9 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/DataCommunicatorInfiniteLoopTest.java @@ -0,0 +1,16 @@ +package com.vaadin.tests.components.grid; + +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class DataCommunicatorInfiniteLoopTest extends SingleBrowserTest { + + @Test + public void grid_does_not_get_stuck_in_infinite_loop() { + openTestURL(); + waitUntil(driver -> driver.findElement(By.className("v-grid-body")) + .findElements(By.className("v-grid-row")).size() == 1); + } +} |