-
Notifications
You must be signed in to change notification settings - Fork 4
Searching Trees
Warning
The documentation below has not been updated to the newest version
As the JsonValue
represents a virtual or expected tree the API to search this
tree is quite limited as any search has to build upon the JsonNode
API which
reflects the actual tree.
For convenience the subtree of a JsonObject
can be searched for an object node
that satisfies a particular shape and test Predicate
:
JsonObject match = root.find(JsonPasswordValidation.class, obj -> true);
The above example finds the first object in the subtree that successfully can
be "cast" to a JsonPasswordValidation
object, meaning it has all its @Expected
members (same as
calling obj.isA(JsonPasswordValidation.class)
on each potential object in the
subtree).
JsonObject match = root.find(JsonPasswordValidation.class, validation -> !validation.isValidPassword());
In the second example the search is extended by an additional Predicate
. Now
the match
is the first JsonPasswordValidation
which has an invalid password.
The JsonObject#find
method builds upon the JsonNode
API which offers a
broader range of search capabilities.
-
JsonNode#find
: find first match that satisfy both a particularJsonNodeType
and aPredicate<JsonNode>
-
JsonNode#count
: count all matches that satisfy both a particularJsonNodeType
andPredicate<JsonNode>
-
JsonNode#visit
: fully generic subtree visitor in form of aConsumer<JsonNode>
The downside of the JsonNode
search API is that dealing with JsonNode
is
more cumbersome and can throw exceptions. Therefore, it can make sense to
implement specific search methods similar to JsonObject#find
in types that
extend JsonObject
.
Searching for an element in a JsonList
can be done using a number of methods:
-
containsAll
: check if the list contains a subset -
contains
: check at least one matching element is contained -
containsUnique
: check that one and only one matching element is contained -
count
: count elements matching aPredicate
test -
first
: find the first matching element
These can be used with JsonArray
as any array can be treated as list
using array.asList(JsonValue.class)
.
Another way to test qualities of a JsonList
is to use one of its toList
methods to turn it into a java.util.List
. The assumption is that the values in
that target list should not be instances of JsonValue
but "usual" java types.
Therefore, any of the toList
methods accepts a Function
to transform
the JsonValue
elements into some java type. At the point of conversion the
virtual tree is accessing the actual tree which means exceptions are possible.
To mitigate this risk there are different variations of the toList
method:
-
toList(Function)
: map and expect all source values to exist, otherwise throws exception -
toList(Function, Object)
: map and use provided default value in case source element does not exist -
toListOfElementsThatExists(Function)
: map and skip those source elements of the list that do not exist
A reason for elements to not exist in an existing array are view transformations. For example if the original elements are objects and a member is extracted for the view not all object might have this member.