Skip to content

feat: views #55

Open
Open
@jbee

Description

@jbee

Meaning a way to easily lay a filter/view over a JsonValue tree. For example based on annotations.

interface JsonUser extends JsonObject {
  @SensitiveInformation
  String getPassword();
}

Now a tree should be filtered

JsonUser user = ...
JsonUser userPublic = user.viewExclude(SensitiveInformation.class);

While this works with "static" information views should also allow to do data driven filtering.
For example, by passing a Predicate<JsonUserField> so a logic can be added when to include a JsonUserField that is based on the data in a JsonUserField value, like a isConfidential() boolean property.

There are two variants of views:

  • a true view as a filter in the proxy - this is likely easy to implement in the proxy handler with some additional logic but it will only work for access via the proxy
  • a mapped JSON view that filters the underlying - this requires a model of the interfaces to know which properties to affect when processing the JSON content, but this is much safer and once produced has no overhead

Filter Models

This is an idea that maybe has best of both worlds/variants (as described above).

In a first step a filter model would be created by some process. This is a tree of what values to look at in a tree.

record JsonFilter<T extends JsonValue>(
  Class<T> as,
  Predicate<T> test,  
  Map<String,JsonFilter<T>> itemsByPath) {}

The model would then using structure like this

new JsonFilter(JsonGroup.class, null,
  Map.of("user", new JsonFilter(JsonUser.class, JsonUser::isInternal, Map.of()));

This would be a dynamic model that might remove the $.user from a UserGroup root object based on the actual users isInternal() property.

From this model and an actual value one can compute the removal operations to do.
In some models the test may not be dynamic but already decided as model creation.
For such models it is possible to create a patch of remove operations without an actual value.
The key in the map for the items is a path segment with array indexes being encoded as [i].
A special index would be used [*]to say "for all" items, similarly * alone means for all members of an object.
To access the member named * one uses the {*} variant of the name.

Models can be created in many different ways, for example by making an annotation analysis where a marker annotation marks all properties that should be filtered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions