From 624923ec7ca88fccda69de7348d49fa3a0b6b49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20J=C3=A4ckle?= Date: Wed, 29 Nov 2023 20:36:07 +0100 Subject: [PATCH] #1826 fix JsonFieldSelectorTrie logic for objects and parts of those objects both being included in selected fields --- .../ditto/json/JsonFieldSelectorTrie.java | 16 +++++++++- .../ditto/json/JsonFieldSelectorTrieTest.java | 30 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/json/src/main/java/org/eclipse/ditto/json/JsonFieldSelectorTrie.java b/json/src/main/java/org/eclipse/ditto/json/JsonFieldSelectorTrie.java index 622558d3dd..eb188195a5 100644 --- a/json/src/main/java/org/eclipse/ditto/json/JsonFieldSelectorTrie.java +++ b/json/src/main/java/org/eclipse/ditto/json/JsonFieldSelectorTrie.java @@ -100,7 +100,21 @@ private JsonFieldSelectorTrie addJsonKeyIterator(final Iterator iterato if (iterator.hasNext()) { final JsonKey key = iterator.next(); children.compute(key, (theKey, theChild) -> { - final JsonFieldSelectorTrie child = theChild != null ? theChild : new JsonFieldSelectorTrie(); + final JsonFieldSelectorTrie child; + if (theChild != null) { + if (iterator.hasNext()) { + if (theChild.children.isEmpty()) { + return theChild; + } else { + child = theChild; + } + } else { + child = new JsonFieldSelectorTrie(); + } + } else { + child = new JsonFieldSelectorTrie(); + } + return child.addJsonKeyIterator(iterator); }); } diff --git a/json/src/test/java/org/eclipse/ditto/json/JsonFieldSelectorTrieTest.java b/json/src/test/java/org/eclipse/ditto/json/JsonFieldSelectorTrieTest.java index 6efaf4c38c..aba3c90517 100644 --- a/json/src/test/java/org/eclipse/ditto/json/JsonFieldSelectorTrieTest.java +++ b/json/src/test/java/org/eclipse/ditto/json/JsonFieldSelectorTrieTest.java @@ -48,6 +48,36 @@ public void trieWithNonemptyPaths() { assertThat(getDescendantKeys(underTest, "c")).isEmpty(); } + @Test + public void trieWithJsonObjectAndCertainFieldInSameJsonObject() { + // given + // a field selector containing both, a "field" inside an "object" and the "object" itself + final JsonFieldSelector fieldSelector = JsonFieldSelector.newInstance("object/field", "object"); + + // when + final JsonFieldSelectorTrie underTest = JsonFieldSelectorTrie.of(fieldSelector); + + // then + assertThat(getDescendantKeys(underTest)).isEqualTo(keySetOf("object")); + // ensure that not only the "field" is contained, but the complete "object" instead: + assertThat(getDescendantKeys(underTest, "object")).isEmpty(); + } + + @Test + public void trieWithJsonObjectAndCertainFieldInSameJsonObjectOrderSwapped() { + // given + // a field selector containing both, a "field" inside an "object" and the "object" itself + final JsonFieldSelector fieldSelectorReverse = JsonFieldSelector.newInstance("object", "object/field"); + + // when + final JsonFieldSelectorTrie underTestReverse = JsonFieldSelectorTrie.of(fieldSelectorReverse); + + // then + assertThat(getDescendantKeys(underTestReverse)).isEqualTo(keySetOf("object")); + // ensure that not only the "field" is contained, but the complete "object" instead: + assertThat(getDescendantKeys(underTestReverse, "object")).isEmpty(); + } + private static Set keySetOf(final String... keyNames) { return Arrays.stream(keyNames).map(JsonKey::of).collect(Collectors.toSet()); }