Skip to content

Commit 1c66e49

Browse files
authored
Fix regression from #4008, optimize ObjectNode.findValue(s) and findParent(s) (#4230)
1 parent 04daeab commit 1c66e49

File tree

3 files changed

+93
-33
lines changed

3 files changed

+93
-33
lines changed

release-notes/VERSION-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Project: jackson-databind
1313
#4216: Primitive array deserializer cannot being captured by `DeserializerModifier`
1414
(reported by @SakuraKoi)
1515
(fix contributed by Joo-Hyuk K)
16+
#4229 JsonNode findValues and findParents missing expected values in 2.16.0
17+
(reported by @gcookemoto)
18+
(fix contributed by Joo-Hyuk K)
1619

1720
2.16.0 (15-Nov-2023)
1821

src/main/java/com/fasterxml/jackson/databind/node/ObjectNode.java

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -382,37 +382,32 @@ public JsonNode findValue(String propertyName)
382382
@Override
383383
public List<JsonNode> findValues(String propertyName, List<JsonNode> foundSoFar)
384384
{
385-
JsonNode jsonNode = _children.get(propertyName);
386-
if (jsonNode != null) {
387-
if (foundSoFar == null) {
388-
foundSoFar = new ArrayList<>();
385+
for (Map.Entry<String, JsonNode> entry : _children.entrySet()) {
386+
if (propertyName.equals(entry.getKey())) {
387+
if (foundSoFar == null) {
388+
foundSoFar = new ArrayList<JsonNode>();
389+
}
390+
foundSoFar.add(entry.getValue());
391+
} else { // only add children if parent not added
392+
foundSoFar = entry.getValue().findValues(propertyName, foundSoFar);
389393
}
390-
foundSoFar.add(jsonNode);
391-
return foundSoFar;
392-
}
393-
394-
// only add children if parent not added
395-
for (JsonNode child : _children.values()) {
396-
foundSoFar = child.findValues(propertyName, foundSoFar);
397394
}
398395
return foundSoFar;
399396
}
400397

401398
@Override
402399
public List<String> findValuesAsText(String propertyName, List<String> foundSoFar)
403400
{
404-
JsonNode jsonNode = _children.get(propertyName);
405-
if (jsonNode != null) {
406-
if (foundSoFar == null) {
407-
foundSoFar = new ArrayList<>();
401+
for (Map.Entry<String, JsonNode> entry : _children.entrySet()) {
402+
if (propertyName.equals(entry.getKey())) {
403+
if (foundSoFar == null) {
404+
foundSoFar = new ArrayList<String>();
405+
}
406+
foundSoFar.add(entry.getValue().asText());
407+
} else { // only add children if parent not added
408+
foundSoFar = entry.getValue().findValuesAsText(propertyName,
409+
foundSoFar);
408410
}
409-
foundSoFar.add(jsonNode.asText());
410-
return foundSoFar;
411-
}
412-
413-
// only add children if parent not added
414-
for (JsonNode child : _children.values()) {
415-
foundSoFar = child.findValuesAsText(propertyName, foundSoFar);
416411
}
417412
return foundSoFar;
418413
}
@@ -436,18 +431,16 @@ public ObjectNode findParent(String propertyName)
436431
@Override
437432
public List<JsonNode> findParents(String propertyName, List<JsonNode> foundSoFar)
438433
{
439-
JsonNode jsonNode = _children.get(propertyName);
440-
if (jsonNode != null) {
441-
if (foundSoFar == null) {
442-
foundSoFar = new ArrayList<>();
434+
for (Map.Entry<String, JsonNode> entry : _children.entrySet()) {
435+
if (propertyName.equals(entry.getKey())) {
436+
if (foundSoFar == null) {
437+
foundSoFar = new ArrayList<JsonNode>();
438+
}
439+
foundSoFar.add(this);
440+
} else { // only add children if parent not added
441+
foundSoFar = entry.getValue()
442+
.findParents(propertyName, foundSoFar);
443443
}
444-
foundSoFar.add(this);
445-
return foundSoFar;
446-
}
447-
448-
// only add children if parent not added
449-
for (JsonNode child : _children.values()) {
450-
foundSoFar = child.findParents(propertyName, foundSoFar);
451444
}
452445
return foundSoFar;
453446
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.fasterxml.jackson.databind.node;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import com.fasterxml.jackson.core.JsonParser;
7+
import com.fasterxml.jackson.databind.JsonNode;
8+
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import org.junit.jupiter.api.Assertions;
10+
import org.junit.jupiter.api.Test;
11+
12+
import static com.fasterxml.jackson.databind.BaseMapTest.jsonMapperBuilder;
13+
import static com.fasterxml.jackson.databind.BaseTest.a2q;
14+
15+
// [databind#4229] JsonNode findValues and findParents missing expected values
16+
public class MissingValues4229Test
17+
{
18+
19+
private final String JSON = a2q("{"
20+
+ " 'target': 'target1'," // Found in <= 2.15.3 and 2.16.0
21+
+ " 'object1': {"
22+
+ " 'target': 'target2' " // Found in <= 2.15.3, but not in 2.16.0
23+
+ " },"
24+
+ " 'object2': {"
25+
+ " 'target': { " // Found in <= 2.15.3, but not in 2.16.0
26+
+ " 'target': 'ignoredAsParentIsTarget'" // Expect not to be found (as sub-tree search ends when parent is found)
27+
+ " }"
28+
+ " }"
29+
+ "}");
30+
31+
private final ObjectMapper objectMapper = jsonMapperBuilder()
32+
.configure(JsonParser.Feature.ALLOW_COMMENTS, true)
33+
.build();
34+
35+
@Test
36+
public void testFindValues() throws Exception
37+
{
38+
JsonNode rootNode = objectMapper.readTree(JSON);
39+
40+
List<JsonNode> expectedNodes = new ArrayList<>();
41+
expectedNodes.add(rootNode.at("/target"));
42+
expectedNodes.add(rootNode.at("/object1/target"));
43+
expectedNodes.add(rootNode.at("/object2/target"));
44+
45+
List<JsonNode> actualNodes = rootNode.findValues("target");
46+
47+
Assertions.assertEquals(expectedNodes, actualNodes);
48+
}
49+
50+
@Test
51+
public void testFindParents() throws Exception
52+
{
53+
JsonNode rootNode = objectMapper.readTree(JSON);
54+
55+
List<JsonNode> expectedNodes = new ArrayList<>();
56+
expectedNodes.add(rootNode.at(""));
57+
expectedNodes.add(rootNode.at("/object1"));
58+
expectedNodes.add(rootNode.at("/object2"));
59+
60+
List<JsonNode> foundNodes = rootNode.findParents("target");
61+
62+
Assertions.assertEquals(expectedNodes, foundNodes);
63+
}
64+
}

0 commit comments

Comments
 (0)