aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <legioth@gmail.com>2017-05-18 16:11:58 +0300
committerPekka Hyvönen <pekka@vaadin.com>2017-05-18 16:11:58 +0300
commit23d65678faf5b0ae59b380d7dbc86e0f9db858cf (patch)
tree3f8e2a39ed0e24e1569f04bbba15c59b8ef43ea2
parent88429109c2f8e77fb3a9ef7b5ab51d51e7dcaa58 (diff)
downloadvaadin-framework-23d65678faf5b0ae59b380d7dbc86e0f9db858cf.tar.gz
vaadin-framework-23d65678faf5b0ae59b380d7dbc86e0f9db858cf.zip
Add stream variants for the child item provider shorthands (#9375)
-rw-r--r--server/src/main/java/com/vaadin/data/HasHierarchicalDataProvider.java44
-rw-r--r--server/src/main/java/com/vaadin/data/TreeData.java20
-rw-r--r--server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java26
3 files changed, 86 insertions, 4 deletions
diff --git a/server/src/main/java/com/vaadin/data/HasHierarchicalDataProvider.java b/server/src/main/java/com/vaadin/data/HasHierarchicalDataProvider.java
index e43b9d6b77..52ea205663 100644
--- a/server/src/main/java/com/vaadin/data/HasHierarchicalDataProvider.java
+++ b/server/src/main/java/com/vaadin/data/HasHierarchicalDataProvider.java
@@ -100,6 +100,50 @@ public interface HasHierarchicalDataProvider<T> extends HasDataProvider<T> {
}
/**
+ * Sets the root data items of this component provided as a stream and
+ * recursively populates them with child items with the given value
+ * provider.
+ * <p>
+ * The provided items are wrapped into a {@link TreeDataProvider} backed by
+ * a flat {@link TreeData} structure. The data provider instance is used as
+ * a parameter for the {@link #setDataProvider(DataProvider)} method. It
+ * means that the items collection can be accessed later on via
+ * {@link #getTreeData()}:
+ *
+ * <pre>
+ * <code>
+ * Stream<Person> grandParents = getGrandParents();
+ * HasHierarchicalDataProvider<Person> treeGrid = new TreeGrid<>();
+ * treeGrid.setItems(grandParents, Person::getChildren);
+ * ...
+ *
+ * TreeData<Person> data = treeGrid.getTreeData();
+ * </code>
+ * </pre>
+ * <p>
+ * The returned {@link TreeData} instance may be used as-is to add, remove
+ * or modify items in the hierarchy. These modifications to the object are
+ * not automatically reflected back to the TreeGrid. Items modified should
+ * be refreshed with {@link HierarchicalDataProvider#refreshItem(Object)}
+ * and when adding or removing items
+ * {@link HierarchicalDataProvider#refreshAll()} should be called.
+ *
+ * @param rootItems
+ * the root items to display, not {@code null}
+ * @param childItemProvider
+ * the value provider used to recursively populate the given root
+ * items with child items, not {@code null}
+ */
+ public default void setItems(Stream<T> rootItems,
+ ValueProvider<T, Stream<T>> childItemProvider) {
+ Objects.requireNonNull(rootItems, "Given root items may not be null");
+ Objects.requireNonNull(childItemProvider,
+ "Given child item provider may not be null");
+ setDataProvider(new TreeDataProvider<>(
+ new TreeData<T>().addItems(rootItems, childItemProvider)));
+ }
+
+ /**
* Sets the data items of this component provided as a collection.
* <p>
* The provided items are wrapped into a {@link TreeDataProvider} backed by
diff --git a/server/src/main/java/com/vaadin/data/TreeData.java b/server/src/main/java/com/vaadin/data/TreeData.java
index f5f9709462..2311a71984 100644
--- a/server/src/main/java/com/vaadin/data/TreeData.java
+++ b/server/src/main/java/com/vaadin/data/TreeData.java
@@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.vaadin.data.provider.TreeDataProvider;
@@ -227,6 +228,25 @@ public class TreeData<T> implements Serializable {
}
/**
+ * Adds the given items as root items and uses the given value provider to
+ * recursively populate children of the root items.
+ *
+ * @param rootItems
+ * the root items to add
+ * @param childItemProvider
+ * the value provider used to recursively populate this TreeData
+ * from the given root items
+ * @return this
+ */
+ public TreeData<T> addItems(Stream<T> rootItems,
+ ValueProvider<T, Stream<T>> childItemProvider) {
+ // Must collect to lists since the algorithm iterates multiple times
+ return addItems(rootItems.collect(Collectors.toList()),
+ item -> childItemProvider.apply(item)
+ .collect(Collectors.toList()));
+ }
+
+ /**
* Remove a given item from this structure. Additionally, this will
* recursively remove any descendants of the item.
*
diff --git a/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java b/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java
index 3f9f1f6e94..f0b2d5f81f 100644
--- a/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java
+++ b/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java
@@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
@@ -12,8 +13,8 @@ import org.junit.Test;
import com.vaadin.data.TreeData;
import com.vaadin.server.SerializablePredicate;
-public class TreeDataProviderTest extends
- DataProviderTestBase<TreeDataProvider<StrBean>> {
+public class TreeDataProviderTest
+ extends DataProviderTestBase<TreeDataProvider<StrBean>> {
private TreeData<StrBean> data;
private List<StrBean> flattenedData;
@@ -46,8 +47,7 @@ public class TreeDataProviderTest extends
@Test(expected = IllegalArgumentException.class)
public void treeData_add_item_parent_not_in_hierarchy_throws() {
- new TreeData<>().addItem(new StrBean("", 0, 0),
- new StrBean("", 0, 0));
+ new TreeData<>().addItem(new StrBean("", 0, 0), new StrBean("", 0, 0));
}
@Test(expected = NullPointerException.class)
@@ -99,6 +99,24 @@ public class TreeDataProviderTest extends
}
@Test
+ public void populate_treeData_with_stream_child_item_provider() {
+ TreeData<String> stringData = new TreeData<>();
+ Stream<String> rootItems = Stream.of("a", "b", "c");
+ stringData.addItems(rootItems, item -> {
+ if (item.length() >= 3 || item.startsWith("c")) {
+ return Stream.empty();
+ }
+ return Stream.of(item + "/a", item + "/b", item + "/c");
+ });
+ Assert.assertEquals(stringData.getChildren("a"),
+ Arrays.asList("a/a", "a/b", "a/c"));
+ Assert.assertEquals(stringData.getChildren("b"),
+ Arrays.asList("b/a", "b/b", "b/c"));
+ Assert.assertEquals(stringData.getChildren("c"), Arrays.asList());
+ Assert.assertEquals(stringData.getChildren("a/b"), Arrays.asList());
+ }
+
+ @Test
public void setFilter() {
getDataProvider().setFilter(item -> item.getValue().equals("Xyz")
|| item.getValue().equals("Baz"));