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 7e04e472e7af2a14baf6c16968b1bd00bed624a8
Author: rishabhdaim <[email protected]>
AuthorDate: Fri Aug 1 16:13:42 2025 +0530

    OAK-11832 : replaced Guava's TreeTraversal with OAK commons
---
 .../jackrabbit/oak/commons/TreeTraverser.java      | 158 +++++++++++
 .../oak/commons/collections/IterableUtils.java     |   2 -
 .../jackrabbit/oak/commons/package-info.java       |   2 +-
 .../jackrabbit/oak/commons/TreeTraverserTest.java  | 294 +++++++++++++++++++++
 .../index/property/jmx/PropertyIndexStats.java     |  21 +-
 .../plugins/index/lucene/LuceneIndexMBeanImpl.java |  19 +-
 .../lucene/property/HybridPropertyIndexInfo.java   |  16 +-
 .../index/lucene/property/RecursiveDeleteTest.java |  14 +-
 .../tika/NodeStoreBinaryResourceProvider.java      |  16 +-
 .../oak/plugins/document/DocumentNodeState.java    |  14 +-
 10 files changed, 494 insertions(+), 62 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/TreeTraverser.java
new file mode 100644
index 0000000000..c0e93e8770
--- /dev/null
+++ 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/TreeTraverser.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.commons;
+
+import org.apache.commons.collections4.FluentIterable;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.function.Function;
+
+public class TreeTraverser {
+
+    private TreeTraverser() {
+        // no instances for you
+    }
+
+    /**
+     * Returns an iterator that traverses a tree structure in pre-order. Null 
nodes are strictly forbidden.
+     * <p>
+     * In pre-order traversal, the current node is visited first, followed by 
its children
+     * from left to right. This method creates an iterator that produces tree 
nodes in this order.
+     *
+     * @param <T> the type of value in the tree nodes
+     * @param root the root node of the tree, may be null
+     * @param childExtractor function to extract children from a node, must 
not be null
+     * @return an iterator that traverses the tree in pre-order
+     * @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) {
+
+        Objects.requireNonNull(childExtractor, "Children extractor function 
must not be null");
+
+        if (root == null) {
+            return FluentIterable.empty();
+        }
+
+        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;
+                    }
+                };
+            }
+        });
+    }
+
+    /**
+     * Returns an iterator that traverses a tree structure in breadth-first 
order.
+     * Null nodes are strictly forbidden.
+     * <p>
+     * In breadth-first traversal, all nodes at a given level are visited 
before any nodes
+     * at the next level. This creates a level-by-level traversal pattern, 
starting from the root
+     * and moving downward through the tree.
+     *
+     * @param <T> the type of value in the tree nodes
+     * @param root the root node of the tree, may be null
+     * @param childExtractor function to extract children from a node, must 
not be null
+     * @return a fluent iterable that traverses the tree in breadth-first order
+     * @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) {
+        Objects.requireNonNull(childExtractor, "Children extractor function 
must not be null");
+
+        if (root == null) {
+            return FluentIterable.empty();
+        }
+
+        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;
+                    }
+                };
+            }
+        });
+    }
+}
diff --git 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
index 4f93afc75f..f7e490d68c 100644
--- 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
+++ 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/collections/IterableUtils.java
@@ -23,12 +23,10 @@ import 
org.apache.jackrabbit.oak.commons.conditions.Validate;
 import org.jetbrains.annotations.NotNull;
 
 import java.lang.reflect.Array;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
-import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.function.Function;
 import java.util.function.Predicate;
diff --git 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/package-info.java 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/package-info.java
index 718a93ef89..628d8b92bb 100644
--- 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/package-info.java
+++ 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("2.4.0")
+@Version("2.5.0")
 package org.apache.jackrabbit.oak.commons;
 
 import org.osgi.annotation.versioning.Version;
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/TreeTraverserTest.java
new file mode 100644
index 0000000000..2978a97799
--- /dev/null
+++ 
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/TreeTraverserTest.java
@@ -0,0 +1,294 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.commons;
+
+import org.apache.commons.collections4.FluentIterable;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Unit cases for {@link TreeTraverser}
+ */
+public class TreeTraverserTest {
+
+    @Test
+    public void testPreOrderTraversalWithNormalTree() {
+        // Create a simple tree structure:
+        //       1
+        //     /   \
+        //    2     3
+        //   / \   / \
+        //  4   5 6   7
+        Node root = new Node(1,
+                new Node(2,
+                        new Node(4),
+                        new Node(5)),
+                new Node(3,
+                        new Node(6),
+                        new Node(7)));
+
+        List<Integer> result = TreeTraverser.preOrderTraversal(root, 
Node::getChildren)
+                .transform(Node::getValue)
+                .toList();
+
+        // In pre-order: visit root, then left subtree, then right subtree
+        Assert.assertEquals(Arrays.asList(1, 2, 4, 5, 3, 6, 7), result);
+    }
+
+    @Test
+    public void testPreOrderTraversalWithNullRoot() {
+        FluentIterable<Node> result = TreeTraverser.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)
+                .transform(Node::getValue)
+                .toList();
+
+        Assert.assertEquals(Collections.singletonList(1), result);
+    }
+
+    @Test
+    public void testPreOrderTraversalWithAsymmetricTree() {
+        // Create an asymmetric tree:
+        //       1
+        //     /   \
+        //    2     3
+        //   /       \
+        //  4         7
+        //   \
+        //    5
+        Node root = new Node(1,
+                new Node(2,
+                        new Node(4,
+                                new Node(5))),
+                new Node(3,
+                        new Node(7)));
+
+        List<Integer> result = TreeTraverser.preOrderTraversal(root, 
Node::getChildren)
+                .transform(Node::getValue)
+                .toList();
+
+        // In pre-order: visit nodes as they're encountered depth-first
+        Assert.assertEquals(Arrays.asList(1, 2, 4, 5, 3, 7), result);
+    }
+
+    @Test
+    public void testPreOrderTraversalWithNullChildExtractor() {
+        Node root = new Node(1);
+        Assert.assertThrows(NullPointerException.class, () -> 
TreeTraverser.preOrderTraversal(root, null));
+    }
+
+    @Test
+    public void testPreOrderTraversalWithDeepTree() {
+        // Create a deep tree with many levels (linked-list-like)
+        Node n1 = new Node(1);
+        Node n2 = new Node(2);
+        Node n3 = new Node(3);
+        Node n4 = new Node(4);
+        Node n5 = new Node(5);
+
+        n1.addChild(n2);
+        n2.addChild(n3);
+        n3.addChild(n4);
+        n4.addChild(n5);
+
+        List<Integer> result = TreeTraverser.preOrderTraversal(n1, 
Node::getChildren)
+                .transform(Node::getValue)
+                .toList();
+
+        // Should visit in depth-first order
+        Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), result);
+    }
+
+    @Test
+    public void testPreOrderTraversalWithBinarySearchTree() {
+        // Create a binary search tree structure
+        //        4
+        //      /   \
+        //     2     6
+        //    / \   / \
+        //   1   3 5   7
+        Node root = new Node(4,
+                new Node(2,
+                        new Node(1),
+                        new Node(3)),
+                new Node(6,
+                        new Node(5),
+                        new Node(7)));
+
+        List<Integer> result = TreeTraverser.preOrderTraversal(root, 
Node::getChildren)
+                .transform(Node::getValue)
+                .toList();
+
+        // In pre-order: root, left subtree, right subtree
+        Assert.assertEquals(Arrays.asList(4, 2, 1, 3, 6, 5, 7), result);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPreOrderTraversalWithNullChildren() {
+        // A tree with some null children
+        Node root = new Node(1,
+                null,
+                new Node(3));
+
+        TreeTraverser.preOrderTraversal(root, 
Node::getChildren).transform(Node::getValue).forEach(System.out::println);
+
+        Assert.fail("Shouldn't reach here");
+    }
+
+    @Test
+    public void testBreadthFirstTraversalWithNormalTree() {
+        // Create a simple tree structure:
+        //       1
+        //     /   \
+        //    2     3
+        //   / \   / \
+        //  4   5 6   7
+        Node root = new Node(1,
+                new Node(2,
+                        new Node(4),
+                        new Node(5)),
+                new Node(3,
+                        new Node(6),
+                        new Node(7)));
+
+        List<Integer> result = TreeTraverser.breadthFirstTraversal(root, 
Node::getChildren)
+                .transform(Node::getValue)
+                .toList();
+
+        Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7), result);
+    }
+
+    @Test
+    public void testBreadthFirstTraversalWithNullRoot() {
+        FluentIterable<Node> result = 
TreeTraverser.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)
+                .transform(Node::getValue)
+                .toList();
+
+        Assert.assertEquals(Collections.singletonList(1), result);
+    }
+
+    @Test
+    public void testBreadthFirstTraversalWithAsymmetricTree() {
+        // Create an asymmetric tree:
+        //       1
+        //     /   \
+        //    2     3
+        //   /       \
+        //  4         7
+        //   \
+        //    5
+        Node root = new Node(1,
+                new Node(2,
+                        new Node(4,
+                                new Node(5))),
+                new Node(3,
+                        new Node(7)));
+
+        List<Integer> result = TreeTraverser.breadthFirstTraversal(root, 
Node::getChildren)
+                .transform(Node::getValue)
+                .toList();
+
+        Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 7, 5), result);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testBreadthFirstTraversalWithNullChildren() {
+        // A tree with some null children
+        Node root = new Node(1,
+                null,
+                new Node(3));
+
+        TreeTraverser.breadthFirstTraversal(root, 
Node::getChildren).transform(Node::getValue).forEach(System.out::println);
+
+        Assert.fail("Shouldn't reach here");
+    }
+
+    @Test
+    public void testBreadthFirstTraversalWithNullChildExtractor() {
+        Node root = new Node(1);
+        Assert.assertThrows(NullPointerException.class, () -> 
TreeTraverser.breadthFirstTraversal(root, null));
+    }
+
+    @Test
+    public void testBreadthFirstTraversalWithDeepTree() {
+        // Create a deep tree with many levels
+        Node n1 = new Node(1);
+        Node n2 = new Node(2);
+        Node n3 = new Node(3);
+        Node n4 = new Node(4);
+        Node n5 = new Node(5);
+
+        n1.addChild(n2);
+        n2.addChild(n3);
+        n3.addChild(n4);
+        n4.addChild(n5);
+
+        List<Integer> result = TreeTraverser.breadthFirstTraversal(n1, 
Node::getChildren)
+                .transform(Node::getValue)
+                .toList();
+
+        Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), result);
+    }
+
+    // Helper class for testing tree traversal
+    private static class Node {
+        private final int value;
+        private final List<Node> children = new ArrayList<>();
+
+        public Node(int value, Node... children) {
+            this.value = value;
+            this.children.addAll(Arrays.asList(children));
+        }
+
+        public int getValue() {
+            return value;
+        }
+
+        public Iterable<Node> getChildren() {
+            return children;
+        }
+
+        public void addChild(Node child) {
+            children.add(child);
+        }
+
+        @Override
+        public String toString() {
+            return Integer.toString(value);
+        }
+    }
+}
\ No newline at end of file
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 279002a4e2..c938052f55 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
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeData;
@@ -36,11 +37,11 @@ import javax.management.openmbean.TabularData;
 import javax.management.openmbean.TabularDataSupport;
 import javax.management.openmbean.TabularType;
 
-import org.apache.jackrabbit.guava.common.collect.TreeTraverser;
 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.collections.IterableUtils;
 import org.apache.jackrabbit.oak.commons.jmx.AnnotatedStandardMBean;
 import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
@@ -50,7 +51,6 @@ import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
-import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -168,17 +168,16 @@ public class PropertyIndexStats extends 
AnnotatedStandardMBean implements Proper
         topLevel:
         for (ChildNodeEntry cne : values) {
             Tree t = TreeFactory.createReadOnlyTree(cne.getNodeState());
-            TreeTraverser<Tree> traverser = new TreeTraverser<Tree>() {
-                @Override
-                public Iterable<Tree> children(@NotNull  Tree root) {
-                    //Break at maxLevel
-                    if (PathUtils.getDepth(root.getPath()) >= maxDepth) {
-                        return Collections.emptyList();
-                    }
-                    return root.getChildren();
+
+            final Function<Tree, Iterable<Tree>> treeGetter = root -> {
+                //Break at maxLevel
+                if (PathUtils.getDepth(root.getPath()) >= maxDepth) {
+                    return Collections.emptyList();
                 }
+                return root.getChildren();
             };
-            for (Tree node : traverser.breadthFirstTraversal(t)) {
+
+            for (Tree node : TreeTraverser.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 bbc50c3c12..5af577f7e4 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,6 +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.collections.IterableUtils;
 import org.apache.jackrabbit.oak.commons.jmx.AnnotatedStandardMBean;
 import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
@@ -90,13 +91,10 @@ import org.apache.lucene.store.FSDirectory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.NumericUtils;
-import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.jackrabbit.guava.common.collect.TreeTraverser;
-
 public class LuceneIndexMBeanImpl extends AnnotatedStandardMBean implements 
LuceneIndexMBean {
 
     private static final boolean LOAD_INDEX_FOR_STATS = 
Boolean.parseBoolean(System.getProperty("oak.lucene.LoadIndexForStats", 
"false"));
@@ -558,18 +556,15 @@ public class LuceneIndexMBeanImpl extends 
AnnotatedStandardMBean implements Luce
         int maxPathLimitBreachedAtLevel = -1;
         topLevel:
         for (LuceneDoc doc : docs){
-            TreeTraverser<LuceneDoc> traverser = new 
TreeTraverser<LuceneDoc>() {
-                @Override
-                public Iterable<LuceneDoc> children(@NotNull LuceneDoc root) {
-                    //Break at maxLevel
-                    if (root.depth >= maxLevel) {
-                        return Collections.emptyList();
-                    }
-                    return root.getChildren();
+
+            final Function<LuceneDoc, Iterable<LuceneDoc>> docGetter = root -> 
{
+                if (root.depth >= maxLevel) {
+                    return Collections.emptyList();
                 }
+                return root.getChildren();
             };
 
-            for (LuceneDoc node : traverser.breadthFirstTraversal(doc)) {
+            for (LuceneDoc node : TreeTraverser.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 5bb0d507cd..b3de7ec0c2 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
@@ -21,8 +21,9 @@ package 
org.apache.jackrabbit.oak.plugins.index.lucene.property;
 
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 
-import org.apache.jackrabbit.guava.common.collect.TreeTraverser;
+import org.apache.jackrabbit.oak.commons.TreeTraverser;
 import org.apache.jackrabbit.oak.commons.collections.IterableUtils;
 import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
@@ -88,15 +89,12 @@ public class HybridPropertyIndexInfo {
     }
 
     private void collectCounts(NodeState bucket) {
-        TreeTraverser<NodeState> t = new TreeTraverser<NodeState>() {
-            @Override
-            public Iterable<NodeState> children(NodeState root) {
-                return IterableUtils.transform(root.getChildNodeEntries(), 
ChildNodeEntry::getNodeState);
-            }
-        };
+
+        Function<NodeState, Iterable<NodeState>> children = root -> 
IterableUtils.transform(root.getChildNodeEntries(), 
ChildNodeEntry::getNodeState);
+
         AtomicInteger matches = new AtomicInteger();
-        int totalCount = t.preOrderTraversal(bucket)
-                .transform((st) -> {
+        int totalCount = TreeTraverser.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 3bf2ab378a..ade524afff 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
@@ -24,9 +24,10 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 
-import org.apache.jackrabbit.guava.common.collect.TreeTraverser;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.commons.TreeTraverser;
 import org.apache.jackrabbit.oak.commons.collections.IterableUtils;
 import org.apache.jackrabbit.oak.fixture.DocumentMemoryFixture;
 import org.apache.jackrabbit.oak.fixture.MemoryFixture;
@@ -149,13 +150,10 @@ public class RecursiveDeleteTest {
     }
 
     private int getSubtreeCount(NodeState state){
-        TreeTraverser<NodeState> t = new TreeTraverser<NodeState>() {
-            @Override
-            public Iterable<NodeState> children(NodeState root) {
-                return IterableUtils.transform(root.getChildNodeEntries(), 
ChildNodeEntry::getNodeState);
-            }
-        };
-        return t.preOrderTraversal(state).size();
+
+        final Function<NodeState, Iterable<NodeState>> children = root -> 
IterableUtils.transform(root.getChildNodeEntries(), 
ChildNodeEntry::getNodeState);
+
+        return TreeTraverser.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 30144ca739..b7b280ada0 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
@@ -19,12 +19,12 @@
 package org.apache.jackrabbit.oak.plugins.tika;
 
 import org.apache.commons.collections4.FluentIterable;
-import org.apache.jackrabbit.guava.common.collect.TreeTraverser;
 import org.apache.jackrabbit.JcrConstants;
 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.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.jetbrains.annotations.Nullable;
@@ -49,11 +49,10 @@ class NodeStoreBinaryResourceProvider implements 
BinaryResourceProvider {
 
     public FluentIterable<BinaryResource> getBinaries(String path) {
         // had to convert Guava's FluentIterable to Apache Commons Collections 
FluentIterable
-        // TODO once we remove preOrderTraversal() of Guava, we can use Apache 
FluentIterable directly
-        return FluentIterable.of(new OakTreeTraverser()
-                
.preOrderTraversal(createReadOnlyTree(getNode(nodeStore.getRoot(), path)))
+        return TreeTraverser
+                
.preOrderTraversal(createReadOnlyTree(getNode(nodeStore.getRoot(), path)), 
treeTraverser)
                 .transform(new TreeToBinarySource()::apply)
-                .filter(Objects::nonNull));
+                .filter(Objects::nonNull);
     }
 
     private class TreeToBinarySource implements Function<Tree, BinaryResource> 
{
@@ -87,12 +86,7 @@ class NodeStoreBinaryResourceProvider implements 
BinaryResourceProvider {
         }
     }
 
-    private static class OakTreeTraverser extends TreeTraverser<Tree> {
-        @Override
-        public Iterable<Tree> children(Tree root) {
-            return root.getChildren();
-        }
-    }
+    final Function<Tree, Iterable<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 2a49eb09c5..15a3f57d16 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
@@ -23,10 +23,11 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
+import java.util.function.Function;
 
-import org.apache.jackrabbit.guava.common.collect.TreeTraverser;
 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.collections.IterableUtils;
 import org.apache.jackrabbit.oak.commons.collections.IteratorUtils;
 import org.apache.jackrabbit.oak.commons.conditions.Validate;
@@ -496,13 +497,10 @@ public class DocumentNodeState extends 
AbstractDocumentNodeState implements Cach
     }
 
     public Iterable<DocumentNodeState> getAllBundledNodesStates() {
-        return new TreeTraverser<DocumentNodeState>(){
-            @Override
-            public Iterable<DocumentNodeState> children(DocumentNodeState 
root) {
-                return IterableUtils.transform(() -> 
root.getBundledChildren(), ce -> (DocumentNodeState)ce.getNodeState());
-            }
-        }.preOrderTraversal(this)
-         .filter(dns -> !dns.getPath().equals(this.getPath()) ); //Exclude this
+        final Function<DocumentNodeState, Iterable<DocumentNodeState>> 
children = root -> IterableUtils.transform(root::getBundledChildren, ce -> 
(DocumentNodeState) ce.getNodeState());
+
+        return TreeTraverser.preOrderTraversal(this, children)
+                .filter(dns -> !dns.getPath().equals(this.getPath()) ); 
//Exclude this
     }
 
     /**

Reply via email to