Skip to content

Commit 27de45a

Browse files
committed
Tree: add pathSeparatorRegex property, Branch path changes (make path string more prominent), JavaDocs
1 parent e288ecd commit 27de45a

File tree

4 files changed

+73
-43
lines changed

4 files changed

+73
-43
lines changed

objectbox-java/src/main/java/io/objectbox/tree/Branch.java

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package io.objectbox.tree;
22

3+
import io.objectbox.annotation.apihint.Experimental;
4+
35
import javax.annotation.Nullable;
46

57
/**
68
* A branch within a {@link Tree}. May have {@link #branch(String[]) branches} or {@link #leaf(String[]) leaves}.
79
*/
10+
@Experimental
811
public class Branch {
912

1013
private final Tree tree;
@@ -24,7 +27,8 @@ public long getId() {
2427
}
2528

2629
/**
27-
* Get the branch when following the given path starting from this branch.
30+
* Get the branch following the given path of child branches from this branch.
31+
*
2832
* @return null if no matching tree node was found
2933
*/
3034
@Nullable
@@ -36,34 +40,31 @@ public Branch branch(String[] path) {
3640
}
3741

3842
/**
39-
* Get the branch attached to this branch with the given name or
40-
* if {@code isDotSeparatedPath} the branch when following the path
41-
* (e.g. {@code Branch1.Branch2}) starting from this branch.
43+
* Get the branch following the given path of child branches from this branch.
44+
*
4245
* @return null if no matching tree node was found
4346
*/
4447
@Nullable
45-
public Branch branch(String nameOrDotPath, boolean isDotSeparatedPath) {
46-
checkNameOrDotPath(nameOrDotPath);
47-
String[] path;
48-
if (isDotSeparatedPath) {
49-
path = nameOrDotPath.split("\\.");
50-
} else {
51-
path = new String[]{nameOrDotPath};
52-
}
48+
public Branch branch(String pathString) {
49+
checkNameOrPath(pathString);
50+
String[] path = pathString.split(tree.getPathSeparatorRegex());
5351
return branch(path);
5452
}
5553

5654
/**
57-
* Get the branch attached to this branch with the given name.
55+
* Get the child branch directly attached to this branch with the given name.
56+
*
5857
* @return null if no matching tree node was found
5958
*/
6059
@Nullable
61-
public Branch branch(String name) {
62-
return branch(name, false);
60+
public Branch branchChild(String name) {
61+
String[] path = new String[]{name};
62+
return branch(path);
6363
}
6464

6565
/**
66-
* Get the leaf when following the given path starting from this branch.
66+
* Get the leaf following the given path of children from this branch.
67+
*
6768
* @return null if no matching tree node was found
6869
*/
6970
@Nullable
@@ -75,36 +76,33 @@ public Leaf leaf(String[] path) {
7576
}
7677

7778
/**
78-
* Get the leaf attached to this branch with the given name or
79-
* if {@code isDotSeparatedPath} the leaf when following the path
80-
* (e.g. {@code Branch1.Leaf1}) starting from this branch.
79+
* Get the leaf following the given path of children from this branch.
80+
*
8181
* @return null if no matching tree node was found
8282
*/
8383
@Nullable
84-
public Leaf leaf(String nameOrDotPath, boolean isDotSeparatedPath) {
85-
checkNameOrDotPath(nameOrDotPath);
86-
String[] path;
87-
if (isDotSeparatedPath) {
88-
path = nameOrDotPath.split("\\.");
89-
} else {
90-
path = new String[]{nameOrDotPath};
91-
}
84+
public Leaf leaf(String pathString) {
85+
checkNameOrPath(pathString);
86+
String[] path = pathString.split(tree.getPathSeparatorRegex());
9287
return leaf(path);
9388
}
9489

9590
/**
96-
* Get the leaf attached to this branch with the given name.
91+
* Get the child leaf directly attached to this branch with the given name.
92+
*
9793
* @return null if no matching tree node was found
9894
*/
9995
@Nullable
100-
public Leaf leaf(String name) {
101-
return leaf(name, false);
96+
public Leaf leafChild(String name) {
97+
checkNameOrPath(name);
98+
String[] path = new String[]{name};
99+
return leaf(path);
102100
}
103101

104-
private void checkNameOrDotPath(String name) {
102+
private void checkNameOrPath(String name) {
105103
//noinspection ConstantConditions Nullability annotations are not enforced.
106104
if (name == null || name.length() == 0) {
107-
throw new IllegalArgumentException("nameOrDotPath must not be null or empty");
105+
throw new IllegalArgumentException("name/path must not be null or empty");
108106
}
109107
}
110108

objectbox-java/src/main/java/io/objectbox/tree/Leaf.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
import javax.annotation.Nullable;
77
import java.nio.charset.StandardCharsets;
88

9+
/**
10+
* A data leaf represents a data value in a {@link Tree} as a child of a {@link Branch}.
11+
* Each data value has a specific type, e.g. an int or a String.
12+
*/
913
@Experimental
1014
public class Leaf {
1115

@@ -27,6 +31,7 @@ public long getMetaId() {
2731
return node.metaId;
2832
}
2933

34+
/** See {@link PropertyType} for possible types (not all are used here). */
3035
public short getValueType() {
3136
return node.valueType;
3237
}

objectbox-java/src/main/java/io/objectbox/tree/Tree.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class Tree implements Closeable {
3232
private long handle;
3333
private final BoxStore store;
3434
private long rootId;
35+
private String pathSeparatorRegex = "\\.";
3536

3637
/**
3738
* Create a tree instance for the given meta-branch root {@code uid}, or find a singular root if 0 is given.
@@ -66,6 +67,19 @@ long getHandle() {
6667
return handle;
6768
}
6869

70+
/**
71+
* The path separator regex is used to split a string path into individual path names.
72+
* Example: with the default separator, e.g. "Book.Author" becomes ["Book", "Author"].
73+
*/
74+
public String getPathSeparatorRegex() {
75+
return pathSeparatorRegex;
76+
}
77+
78+
/** E.g. use "\\/" to change path strings to "Book/Author"; see {@link #getPathSeparatorRegex()} for details. */
79+
public void setPathSeparatorRegex(String pathSeparatorRegex) {
80+
this.pathSeparatorRegex = pathSeparatorRegex;
81+
}
82+
6983
/**
7084
* The root ID, which the tree was constructed with.
7185
*/

tests/objectbox-java-test/src/test/java/io/objectbox/tree/TreeTest.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,13 @@ public void treePath() {
124124
});
125125

126126
tree.runInReadTx(() -> {
127-
Branch book = root.branch("Book", true);
127+
Branch book = root.branch("Book");
128128
assertNotNull(book);
129129
// get leaf indirectly by traversing branches
130-
Branch author = book.branch("Author");
130+
Branch author = book.branchChild("Author");
131131
assertNotNull(author);
132132

133-
Leaf name = author.leaf("Name");
133+
Leaf name = author.leafChild("Name");
134134
assertNotNull(name);
135135
assertEquals("Tolkien", name.getString());
136136
assertFalse(name.isInt());
@@ -141,18 +141,31 @@ public void treePath() {
141141
assertEquals(author.getId(), name.getParentBranchId());
142142
assertEquals(metaLeafIds[0], name.getMetaId());
143143

144-
Leaf year = author.leaf("Year");
144+
Leaf year = author.leafChild("Year");
145145
assertNotNull(year);
146146
assertEquals(2021, year.getInt());
147147

148-
Leaf height = author.leaf("Height");
148+
Leaf height = author.leafChild("Height");
149149
assertNotNull(height);
150150
assertEquals(12.34, height.getDouble(), 0.0);
151151

152152
// get leaf directly
153153
Leaf name2 = book.leaf(new String[]{"Author", "Name"});
154154
assertNotNull(name2);
155155
assertEquals("Tolkien", name2.getString());
156+
157+
// get leaf directly via path string
158+
name2 = book.leaf("Author.Name");
159+
assertNotNull(name2);
160+
assertEquals("Tolkien", name2.getString());
161+
162+
// get leaf directly via path string with another separator
163+
assertNull(book.leaf("Author/Name"));
164+
tree.setPathSeparatorRegex("\\/");
165+
name2 = book.leaf("Author/Name");
166+
assertNotNull(name2);
167+
assertEquals("Tolkien", name2.getString());
168+
156169
});
157170
}
158171

@@ -162,7 +175,7 @@ public void putValueForExistingLeaf_String() {
162175
long metaNameId = tree.putMetaLeaf(0, metaBranchIds[0], "Name", PropertyType.String);
163176
assertNotEquals(0, metaNameId);
164177
tree.putValue(rootId, metaNameId, "Bookery");
165-
Leaf leaf = root.leaf("Name");
178+
Leaf leaf = root.leafChild("Name");
166179
assertNotNull(leaf);
167180
assertEquals("Bookery", leaf.getString());
168181

@@ -176,7 +189,7 @@ public void putValueForExistingLeaf_String() {
176189
});
177190

178191
tree.runInReadTx(() -> {
179-
Leaf name = root.leaf("Name");
192+
Leaf name = root.leafChild("Name");
180193
assertNotNull(name);
181194
assertEquals("Unseen Library", name.getString());
182195
});
@@ -188,7 +201,7 @@ public void putValueForExistingLeaf_Int() {
188201
long metaYearId = tree.putMetaLeaf(0, metaBranchIds[0], "Year", PropertyType.Int);
189202
assertNotEquals(0, metaYearId);
190203
tree.putValue(rootId, metaYearId, 1982);
191-
Leaf leaf = root.leaf("Year");
204+
Leaf leaf = root.leafChild("Year");
192205
assertNotNull(leaf);
193206
assertEquals(1982, leaf.getInt());
194207

@@ -202,7 +215,7 @@ public void putValueForExistingLeaf_Int() {
202215
});
203216

204217
tree.runInReadTx(() -> {
205-
Leaf year = root.leaf("Year");
218+
Leaf year = root.leafChild("Year");
206219
assertNotNull(year);
207220
assertEquals(1977, year.getInt());
208221
});
@@ -222,7 +235,7 @@ public void concurrentTxs() throws InterruptedException {
222235
} catch (InterruptedException e) {
223236
e.printStackTrace();
224237
}
225-
assertNull(tree.getRoot().branch("Book"));
238+
assertNull(tree.getRoot().branchChild("Book"));
226239
readThreadOK.set(true);
227240
});
228241
});
@@ -247,7 +260,7 @@ public void concurrentTxs() throws InterruptedException {
247260
System.out.println("Thread " + Thread.currentThread().getId() + " entered tree TX");
248261
latch.countDown();
249262
latch.await();
250-
return tree.getRoot().branch("Book");
263+
return tree.getRoot().branchChild("Book");
251264
};
252265
Branch branch = tree.callInReadTx(branchCallable);
253266
assertNull(branch);

0 commit comments

Comments
 (0)