This is an automated email from the ASF dual-hosted git repository. daim pushed a commit to branch OAK-11832 in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 636a3c263caa095982565c1ead015498e2e64ab0 Author: rishabhdaim <[email protected]> AuthorDate: Sat Aug 2 09:21:06 2025 +0530 OAK-11832 : replaced Guava's TreeTraversal with OAK commons --- .../commons/{TreeTraverser.java => Traverser.java} | 144 +++++++++++---------- .../{TreeTraverserTest.java => TraverserTest.java} | 88 ++++++++++--- .../index/property/jmx/PropertyIndexStats.java | 6 +- .../plugins/index/lucene/LuceneIndexMBeanImpl.java | 6 +- .../lucene/property/HybridPropertyIndexInfo.java | 6 +- .../index/lucene/property/RecursiveDeleteTest.java | 6 +- .../tika/NodeStoreBinaryResourceProvider.java | 6 +- .../oak/plugins/document/DocumentNodeState.java | 6 +- 8 files changed, 167 insertions(+), 101 deletions(-) diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/TreeTraverser.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/Traverser.java similarity index 55% rename from oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/TreeTraverser.java rename to oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/Traverser.java index c0e93e8770..824860eba5 100644 --- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/TreeTraverser.java +++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/Traverser.java @@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.commons; import org.apache.commons.collections4.FluentIterable; +import org.apache.commons.collections4.iterators.UnmodifiableIterator; import org.jetbrains.annotations.NotNull; import java.util.ArrayDeque; @@ -31,9 +32,9 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Function; -public class TreeTraverser { +public class Traverser { - private TreeTraverser() { + private Traverser() { // no instances for you } @@ -50,7 +51,7 @@ public class TreeTraverser { * @throws NullPointerException if childExtractor or any child is null */ @NotNull - public static <T> FluentIterable<T> preOrderTraversal(final T root, final @NotNull Function<T, Iterable<T>> childExtractor) { + public static <T> FluentIterable<T> preOrderTraversal(final T root, final @NotNull Function<T, Iterable<? extends T>> childExtractor) { Objects.requireNonNull(childExtractor, "Children extractor function must not be null"); @@ -61,43 +62,48 @@ public class TreeTraverser { return FluentIterable.of(new Iterable<>() { @Override public @NotNull Iterator<T> iterator() { - return new Iterator<>() { - private final Deque<T> stack = new ArrayDeque<>(); - - { - // add first element during initialization - stack.push(root); - } - - @Override - public boolean hasNext() { - return !stack.isEmpty(); - } - - @Override - public T next() { - if (!hasNext()) { - throw new NoSuchElementException("No more nodes in the tree"); - } - - final T current = stack.pop(); - - // Push children in reverse order so they're popped in correct order - List<T> children = new ArrayList<>(); - // NPE if the current is null - childExtractor.apply(current).forEach(children::add); - - for (int i = children.size() - 1; i >= 0; i--) { - // NPE if the child is null - stack.push(children.get(i)); - } - return current; - } - }; + return UnmodifiableIterator.unmodifiableIterator(new PreOrderIterator<>(root, childExtractor)); } }); } + private static final class PreOrderIterator<T> implements Iterator<T> { + + private final Deque<T> stack; + private final Function<T, Iterable<? extends T>> childExtractor; + + public PreOrderIterator(final T root, final Function<T, Iterable<? extends T>> childExtractor) { + this.childExtractor = childExtractor; + this.stack = new ArrayDeque<>(); + // add first element during initialization + stack.push(root); + } + @Override + public boolean hasNext() { + return !stack.isEmpty(); + } + + @Override + public T next() { + if (!hasNext()) { + throw new NoSuchElementException("No more nodes in the tree"); + } + + final T current = stack.pop(); + + // Push children in reverse order so they're popped in correct order + List<T> children = new ArrayList<>(); + // NPE if the current is null + childExtractor.apply(current).forEach(children::add); + + for (int i = children.size() - 1; i >= 0; i--) { + // NPE if the child is null + stack.push(children.get(i)); + } + return current; + } + } + /** * Returns an iterator that traverses a tree structure in breadth-first order. * Null nodes are strictly forbidden. @@ -113,7 +119,7 @@ public class TreeTraverser { * @throws NullPointerException if childExtractor or any child is null */ @NotNull - public static <T> FluentIterable<T> breadthFirstTraversal(final T root, final @NotNull Function<T, Iterable<T>> childExtractor) { + public static <T> FluentIterable<T> breadthFirstTraversal(final T root, final @NotNull Function<T, Iterable<? extends T>> childExtractor) { Objects.requireNonNull(childExtractor, "Children extractor function must not be null"); if (root == null) { @@ -123,36 +129,42 @@ public class TreeTraverser { return FluentIterable.of(new Iterable<>() { @Override public @NotNull Iterator<T> iterator() { - return new Iterator<>() { - private final Deque<T> queue = new ArrayDeque<>(); - - { - // add first element during initialization - queue.addLast(root); - } - - @Override - public boolean hasNext() { - return !queue.isEmpty(); - } - - @Override - public T next() { - if (!hasNext()) { - throw new NoSuchElementException("No more nodes in the tree"); - } - - final T current = queue.removeFirst(); - - // Add all children to the queue (in order) - for (T child : childExtractor.apply(current)) { - // would throw NPE if the child is null - queue.addLast(child); - } - return current; - } - }; + return UnmodifiableIterator.unmodifiableIterator(new BreadthFirstIterator<>(root, childExtractor)); } }); } + + private static final class BreadthFirstIterator<T> implements Iterator<T> { + + private final Deque<T> queue; + private final Function<T, Iterable<? extends T>> childExtractor; + + public BreadthFirstIterator(final T root, final Function<T, Iterable<? extends T>> childExtractor) { + this.queue = new ArrayDeque<>(); + this.childExtractor = childExtractor; + this.queue.add(root); + } + + @Override + public boolean hasNext() { + return !queue.isEmpty(); + } + + @Override + public T next() { + if (!hasNext()) { + throw new NoSuchElementException("No more nodes in the tree"); + } + + final T current = queue.removeFirst(); + + // Add all children to the queue (in order) + for (T child : childExtractor.apply(current)) { + // would throw NPE if the child is null + queue.addLast(child); + } + return current; + } + } } + diff --git a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/TreeTraverserTest.java b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/TraverserTest.java similarity index 73% rename from oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/TreeTraverserTest.java rename to oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/TraverserTest.java index 2978a97799..3690ebe6ac 100644 --- a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/TreeTraverserTest.java +++ b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/TraverserTest.java @@ -29,9 +29,9 @@ import java.util.Collections; import java.util.List; /** - * Unit cases for {@link TreeTraverser} + * Unit cases for {@link Traverser} */ -public class TreeTraverserTest { +public class TraverserTest { @Test public void testPreOrderTraversalWithNormalTree() { @@ -49,7 +49,7 @@ public class TreeTraverserTest { new Node(6), new Node(7))); - List<Integer> result = TreeTraverser.preOrderTraversal(root, Node::getChildren) + List<Integer> result = Traverser.preOrderTraversal(root, Node::getChildren) .transform(Node::getValue) .toList(); @@ -59,14 +59,14 @@ public class TreeTraverserTest { @Test public void testPreOrderTraversalWithNullRoot() { - FluentIterable<Node> result = TreeTraverser.preOrderTraversal(null, Node::getChildren); + FluentIterable<Node> result = Traverser.preOrderTraversal(null, Node::getChildren); Assert.assertTrue(result.isEmpty()); } @Test public void testPreOrderTraversalWithSingleNode() { Node root = new Node(1); - List<Integer> result = TreeTraverser.preOrderTraversal(root, Node::getChildren) + List<Integer> result = Traverser.preOrderTraversal(root, Node::getChildren) .transform(Node::getValue) .toList(); @@ -90,7 +90,7 @@ public class TreeTraverserTest { new Node(3, new Node(7))); - List<Integer> result = TreeTraverser.preOrderTraversal(root, Node::getChildren) + List<Integer> result = Traverser.preOrderTraversal(root, Node::getChildren) .transform(Node::getValue) .toList(); @@ -101,7 +101,7 @@ public class TreeTraverserTest { @Test public void testPreOrderTraversalWithNullChildExtractor() { Node root = new Node(1); - Assert.assertThrows(NullPointerException.class, () -> TreeTraverser.preOrderTraversal(root, null)); + Assert.assertThrows(NullPointerException.class, () -> Traverser.preOrderTraversal(root, null)); } @Test @@ -118,7 +118,7 @@ public class TreeTraverserTest { n3.addChild(n4); n4.addChild(n5); - List<Integer> result = TreeTraverser.preOrderTraversal(n1, Node::getChildren) + List<Integer> result = Traverser.preOrderTraversal(n1, Node::getChildren) .transform(Node::getValue) .toList(); @@ -142,7 +142,7 @@ public class TreeTraverserTest { new Node(5), new Node(7))); - List<Integer> result = TreeTraverser.preOrderTraversal(root, Node::getChildren) + List<Integer> result = Traverser.preOrderTraversal(root, Node::getChildren) .transform(Node::getValue) .toList(); @@ -157,7 +157,7 @@ public class TreeTraverserTest { null, new Node(3)); - TreeTraverser.preOrderTraversal(root, Node::getChildren).transform(Node::getValue).forEach(System.out::println); + Traverser.preOrderTraversal(root, Node::getChildren).transform(Node::getValue).forEach(System.out::println); Assert.fail("Shouldn't reach here"); } @@ -178,23 +178,50 @@ public class TreeTraverserTest { new Node(6), new Node(7))); - List<Integer> result = TreeTraverser.breadthFirstTraversal(root, Node::getChildren) + List<Integer> result = Traverser.breadthFirstTraversal(root, Node::getChildren) .transform(Node::getValue) .toList(); Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7), result); } + @Test + public void testPreOrderTraversalWithTree() { + // Create a tree structure + // 4 + // / \ + // 0,2 6 + // / \ + // 1,3,5 7,8,9 + Node root = new Node(4, + new Node(0), + new Node(2, + new Node(1), + new Node(3), + new Node(5)), + new Node(6, + new Node(7), + new Node(8), + new Node(9))); + + List<Integer> result = Traverser.preOrderTraversal(root, Node::getChildren) + .transform(Node::getValue) + .toList(); + + // In post-order: left subtree, right subtree, root + Assert.assertEquals(Arrays.asList(4, 0, 2, 1, 3, 5, 6, 7, 8, 9), result); + } + @Test public void testBreadthFirstTraversalWithNullRoot() { - FluentIterable<Node> result = TreeTraverser.breadthFirstTraversal(null, Node::getChildren); + FluentIterable<Node> result = Traverser.breadthFirstTraversal(null, Node::getChildren); Assert.assertTrue(result.isEmpty()); } @Test public void testBreadthFirstTraversalWithSingleNode() { Node root = new Node(1); - List<Integer> result = TreeTraverser.breadthFirstTraversal(root, Node::getChildren) + List<Integer> result = Traverser.breadthFirstTraversal(root, Node::getChildren) .transform(Node::getValue) .toList(); @@ -218,7 +245,7 @@ public class TreeTraverserTest { new Node(3, new Node(7))); - List<Integer> result = TreeTraverser.breadthFirstTraversal(root, Node::getChildren) + List<Integer> result = Traverser.breadthFirstTraversal(root, Node::getChildren) .transform(Node::getValue) .toList(); @@ -232,7 +259,7 @@ public class TreeTraverserTest { null, new Node(3)); - TreeTraverser.breadthFirstTraversal(root, Node::getChildren).transform(Node::getValue).forEach(System.out::println); + Traverser.breadthFirstTraversal(root, Node::getChildren).transform(Node::getValue).forEach(System.out::println); Assert.fail("Shouldn't reach here"); } @@ -240,7 +267,7 @@ public class TreeTraverserTest { @Test public void testBreadthFirstTraversalWithNullChildExtractor() { Node root = new Node(1); - Assert.assertThrows(NullPointerException.class, () -> TreeTraverser.breadthFirstTraversal(root, null)); + Assert.assertThrows(NullPointerException.class, () -> Traverser.breadthFirstTraversal(root, null)); } @Test @@ -257,13 +284,40 @@ public class TreeTraverserTest { n3.addChild(n4); n4.addChild(n5); - List<Integer> result = TreeTraverser.breadthFirstTraversal(n1, Node::getChildren) + List<Integer> result = Traverser.breadthFirstTraversal(n1, Node::getChildren) .transform(Node::getValue) .toList(); Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), result); } + @Test + public void testBreadthFirstOrderTraversalWithTree() { + // Create a tree structure + // 4 + // / \ + // 0,2 6 + // / \ + // 1,3,5 7,8,9 + Node root = new Node(4, + new Node(0), + new Node(2, + new Node(1), + new Node(3), + new Node(5)), + new Node(6, + new Node(7), + new Node(8), + new Node(9))); + + List<Integer> result = Traverser.breadthFirstTraversal(root, Node::getChildren) + .transform(Node::getValue) + .toList(); + + // In post-order: left subtree, right subtree, root + Assert.assertEquals(Arrays.asList(4, 0, 2, 6, 1, 3, 5, 7, 8, 9), result); + } + // Helper class for testing tree traversal private static class Node { private final int value; diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexStats.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexStats.java index c938052f55..0986a6f0d7 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexStats.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexStats.java @@ -41,7 +41,7 @@ import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.commons.PathUtils; -import org.apache.jackrabbit.oak.commons.TreeTraverser; +import org.apache.jackrabbit.oak.commons.Traverser; import org.apache.jackrabbit.oak.commons.collections.IterableUtils; import org.apache.jackrabbit.oak.commons.jmx.AnnotatedStandardMBean; import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard; @@ -169,7 +169,7 @@ public class PropertyIndexStats extends AnnotatedStandardMBean implements Proper for (ChildNodeEntry cne : values) { Tree t = TreeFactory.createReadOnlyTree(cne.getNodeState()); - final Function<Tree, Iterable<Tree>> treeGetter = root -> { + final Function<Tree, Iterable<? extends Tree>> treeGetter = root -> { //Break at maxLevel if (PathUtils.getDepth(root.getPath()) >= maxDepth) { return Collections.emptyList(); @@ -177,7 +177,7 @@ public class PropertyIndexStats extends AnnotatedStandardMBean implements Proper return root.getChildren(); }; - for (Tree node : TreeTraverser.breadthFirstTraversal(t, treeGetter)) { + for (Tree node : Traverser.breadthFirstTraversal(t, treeGetter)) { PropertyState matchState = node.getProperty("match"); boolean match = matchState == null ? false : matchState.getValue(Type.BOOLEAN); int depth = PathUtils.getDepth(node.getPath()); diff --git a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java index 5af577f7e4..f1dd71f446 100644 --- a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java +++ b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java @@ -48,7 +48,7 @@ import javax.management.openmbean.TabularType; import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.jmx.Name; import org.apache.jackrabbit.oak.commons.PathUtils; -import org.apache.jackrabbit.oak.commons.TreeTraverser; +import org.apache.jackrabbit.oak.commons.Traverser; import org.apache.jackrabbit.oak.commons.collections.IterableUtils; import org.apache.jackrabbit.oak.commons.jmx.AnnotatedStandardMBean; import org.apache.jackrabbit.oak.commons.json.JsopBuilder; @@ -557,14 +557,14 @@ public class LuceneIndexMBeanImpl extends AnnotatedStandardMBean implements Luce topLevel: for (LuceneDoc doc : docs){ - final Function<LuceneDoc, Iterable<LuceneDoc>> docGetter = root -> { + final Function<LuceneDoc, Iterable<? extends LuceneDoc>> docGetter = root -> { if (root.depth >= maxLevel) { return Collections.emptyList(); } return root.getChildren(); }; - for (LuceneDoc node : TreeTraverser.breadthFirstTraversal(doc, docGetter)) { + for (LuceneDoc node : Traverser.breadthFirstTraversal(doc, docGetter)) { if (paths.size() < maxPathCount) { paths.add(node.path); } else { diff --git a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java index b3de7ec0c2..37df70899b 100644 --- a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java +++ b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java @@ -23,7 +23,7 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; -import org.apache.jackrabbit.oak.commons.TreeTraverser; +import org.apache.jackrabbit.oak.commons.Traverser; import org.apache.jackrabbit.oak.commons.collections.IterableUtils; import org.apache.jackrabbit.oak.commons.json.JsopBuilder; import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry; @@ -90,10 +90,10 @@ public class HybridPropertyIndexInfo { private void collectCounts(NodeState bucket) { - Function<NodeState, Iterable<NodeState>> children = root -> IterableUtils.transform(root.getChildNodeEntries(), ChildNodeEntry::getNodeState); + Function<NodeState, Iterable<? extends NodeState>> children = root -> IterableUtils.transform(root.getChildNodeEntries(), ChildNodeEntry::getNodeState); AtomicInteger matches = new AtomicInteger(); - int totalCount = TreeTraverser.preOrderTraversal(bucket, children) + int totalCount = Traverser.preOrderTraversal(bucket, children) .transform(st -> { if (st.getBoolean("match")) { matches.incrementAndGet(); diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/RecursiveDeleteTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/RecursiveDeleteTest.java index ade524afff..ce33fe0a3c 100644 --- a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/RecursiveDeleteTest.java +++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/RecursiveDeleteTest.java @@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import org.apache.jackrabbit.oak.api.CommitFailedException; -import org.apache.jackrabbit.oak.commons.TreeTraverser; +import org.apache.jackrabbit.oak.commons.Traverser; import org.apache.jackrabbit.oak.commons.collections.IterableUtils; import org.apache.jackrabbit.oak.fixture.DocumentMemoryFixture; import org.apache.jackrabbit.oak.fixture.MemoryFixture; @@ -151,9 +151,9 @@ public class RecursiveDeleteTest { private int getSubtreeCount(NodeState state){ - final Function<NodeState, Iterable<NodeState>> children = root -> IterableUtils.transform(root.getChildNodeEntries(), ChildNodeEntry::getNodeState); + final Function<NodeState, Iterable<? extends NodeState>> children = root -> IterableUtils.transform(root.getChildNodeEntries(), ChildNodeEntry::getNodeState); - return TreeTraverser.preOrderTraversal(state, children).size(); + return Traverser.preOrderTraversal(state, children).size(); } } diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java index b7b280ada0..ba1add35f3 100644 --- a/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java +++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/tika/NodeStoreBinaryResourceProvider.java @@ -24,7 +24,7 @@ import org.apache.jackrabbit.oak.api.Blob; import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.Type; -import org.apache.jackrabbit.oak.commons.TreeTraverser; +import org.apache.jackrabbit.oak.commons.Traverser; import org.apache.jackrabbit.oak.spi.blob.BlobStore; import org.apache.jackrabbit.oak.spi.state.NodeStore; import org.jetbrains.annotations.Nullable; @@ -49,7 +49,7 @@ class NodeStoreBinaryResourceProvider implements BinaryResourceProvider { public FluentIterable<BinaryResource> getBinaries(String path) { // had to convert Guava's FluentIterable to Apache Commons Collections FluentIterable - return TreeTraverser + return Traverser .preOrderTraversal(createReadOnlyTree(getNode(nodeStore.getRoot(), path)), treeTraverser) .transform(new TreeToBinarySource()::apply) .filter(Objects::nonNull); @@ -86,7 +86,7 @@ class NodeStoreBinaryResourceProvider implements BinaryResourceProvider { } } - final Function<Tree, Iterable<Tree>> treeTraverser = Tree::getChildren; + final Function<Tree, Iterable<? extends Tree>> treeTraverser = Tree::getChildren; @Nullable private static String getString(Tree tree, String name) { diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java index 15a3f57d16..7ef95028b5 100644 --- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java +++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java @@ -27,7 +27,7 @@ import java.util.function.Function; import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.cache.CacheValue; -import org.apache.jackrabbit.oak.commons.TreeTraverser; +import org.apache.jackrabbit.oak.commons.Traverser; import org.apache.jackrabbit.oak.commons.collections.IterableUtils; import org.apache.jackrabbit.oak.commons.collections.IteratorUtils; import org.apache.jackrabbit.oak.commons.conditions.Validate; @@ -497,9 +497,9 @@ public class DocumentNodeState extends AbstractDocumentNodeState implements Cach } public Iterable<DocumentNodeState> getAllBundledNodesStates() { - final Function<DocumentNodeState, Iterable<DocumentNodeState>> children = root -> IterableUtils.transform(root::getBundledChildren, ce -> (DocumentNodeState) ce.getNodeState()); + final Function<DocumentNodeState, Iterable<? extends DocumentNodeState>> children = root -> IterableUtils.transform(root::getBundledChildren, ce -> (DocumentNodeState) ce.getNodeState()); - return TreeTraverser.preOrderTraversal(this, children) + return Traverser.preOrderTraversal(this, children) .filter(dns -> !dns.getPath().equals(this.getPath()) ); //Exclude this }
