This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git
The following commit(s) were added to refs/heads/master by this push:
new a602490 [JOHNZON-336] jsonpatch operators for jsonlogic
a602490 is described below
commit a6024900b68c14e86742dd231ba318d20a18a975
Author: Romain Manni-Bucau <[email protected]>
AuthorDate: Wed Feb 17 10:01:22 2021 +0100
[JOHNZON-336] jsonpatch operators for jsonlogic
---
.../apache/johnzon/jsonlogic/JohnzonJsonLogic.java | 49 +++++++++++++-
.../johnzon/jsonlogic/JohnzonJsonLogicTest.java | 74 ++++++++++++++++++++++
src/site/markdown/index.md | 2 +
3 files changed, 124 insertions(+), 1 deletion(-)
diff --git
a/johnzon-jsonlogic/src/main/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogic.java
b/johnzon-jsonlogic/src/main/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogic.java
index 9691c82..21e7618 100644
---
a/johnzon-jsonlogic/src/main/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogic.java
+++
b/johnzon-jsonlogic/src/main/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogic.java
@@ -24,8 +24,10 @@ import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonBuilderFactory;
import javax.json.JsonException;
+import javax.json.JsonMergePatch;
import javax.json.JsonNumber;
import javax.json.JsonObject;
+import javax.json.JsonPatch;
import javax.json.JsonPointer;
import javax.json.JsonString;
import javax.json.JsonStructure;
@@ -37,6 +39,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiPredicate;
import java.util.stream.Collector;
import java.util.stream.DoubleStream;
@@ -49,13 +52,18 @@ import static java.util.stream.Collectors.joining;
public class JohnzonJsonLogic {
private final JsonProvider provider;
private final Map<String, Operator> operators = new HashMap<>();
- private final Map<String, JsonPointer> pointers = new HashMap<>();
+ private final Map<String, JsonPointer> pointers = new
ConcurrentHashMap<>();
+ private final Map<JsonArray, JsonPatch> jsonPatches = new
ConcurrentHashMap<>();
+ private final Map<JsonValue, JsonMergePatch> jsonMergePatches = new
ConcurrentHashMap<>();
private final JsonBuilderFactory builderFactory;
private boolean cachePointers;
+ private boolean cacheJsonPatches;
+ private boolean cacheJsonMergePatches;
public JohnzonJsonLogic() {
this(JsonProvider.provider());
registerDefaultOperators();
+ registerExtensionsOperators();
}
public JohnzonJsonLogic(final JsonProvider provider) {
@@ -68,6 +76,16 @@ public class JohnzonJsonLogic {
return this;
}
+ public JohnzonJsonLogic cacheJsonPatches() {
+ this.cacheJsonPatches = true;
+ return this;
+ }
+
+ public JohnzonJsonLogic cacheJsonMergePatches() {
+ this.cacheJsonMergePatches = true;
+ return this;
+ }
+
public JohnzonJsonLogic registerOperator(final String name, final Operator
impl) {
operators.put(name, impl);
return this;
@@ -190,6 +208,35 @@ public class JohnzonJsonLogic {
}
}
+ public JohnzonJsonLogic registerExtensionsOperators() {
+ registerOperator("jsonpatch", (logic, config, params) ->
getJsonPatch(config)
+ .apply(JsonStructure.class.cast(params)));
+ registerOperator("jsonmergepatch", (logic, config, params) ->
getJsonMergePatch(config)
+ .apply(params));
+ registerOperator("jsonmergediff", (logic, config, params) -> {
+ final JsonArray array = params.asJsonArray();
+ if (array.size() != 2) {
+ throw new IllegalArgumentException("jsonmergediff should have
2 parameters (in an array): " + array);
+ }
+ return provider.createMergeDiff(config,
array.get(0)).apply(array.get(1));
+ });
+ return this;
+ }
+
+ private JsonPatch getJsonPatch(final JsonValue config) {
+ if (!cacheJsonPatches) {
+ return provider.createPatch(config.asJsonArray());
+ }
+ return jsonPatches.computeIfAbsent(config.asJsonArray(),
provider::createPatch);
+ }
+
+ private JsonMergePatch getJsonMergePatch(final JsonValue config) {
+ if (!cacheJsonPatches) {
+ return provider.createMergePatch(config);
+ }
+ return jsonMergePatches.computeIfAbsent(config,
provider::createMergePatch);
+ }
+
// to not depend on a logger we don't register "log" operation but it is
trivial to do:
public JohnzonJsonLogic registerDefaultOperators() {
registerOperator("log", (logic, config, params) -> {
diff --git
a/johnzon-jsonlogic/src/test/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogicTest.java
b/johnzon-jsonlogic/src/test/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogicTest.java
index f126cfd..53950ab 100644
---
a/johnzon-jsonlogic/src/test/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogicTest.java
+++
b/johnzon-jsonlogic/src/test/java/org/apache/johnzon/jsonlogic/JohnzonJsonLogicTest.java
@@ -25,6 +25,7 @@ import org.junit.Test;
import javax.json.Json;
import javax.json.JsonBuilderFactory;
import javax.json.JsonObject;
+import javax.json.JsonPatch;
import javax.json.JsonValue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
@@ -123,6 +124,79 @@ public class JohnzonJsonLogicTest {
}
@Test
+ public void jsonPatch() {
+ assertEquals(
+ builderFactory.createObjectBuilder()
+ .add("dummy",
builderFactory.createObjectBuilder().add("added", true))
+ .add("foo", "replaced")
+ .build(),
+ jsonLogic.apply(
+ builderFactory.createObjectBuilder()
+ .add("jsonpatch",
builderFactory.createArrayBuilder()
+
.add(builderFactory.createObjectBuilder()
+ .add("op",
JsonPatch.Operation.ADD.operationName())
+ .add("path", "/dummy")
+ .add("value",
builderFactory.createObjectBuilder()
+ .add("added", true)))
+
.add(builderFactory.createObjectBuilder()
+ .add("op",
JsonPatch.Operation.REPLACE.operationName())
+ .add("path", "/foo")
+ .add("value", "replaced")))
+ .build(),
+ Json.createObjectBuilder().add("foo", "bar").build()));
+ }
+
+ @Test
+ public void jsonMergePatch() {
+ assertEquals(
+ builderFactory.createObjectBuilder()
+ .add("a", "z")
+ .add("c", builderFactory.createObjectBuilder()
+ .add("d", "e"))
+ .build(),
+ jsonLogic.apply(
+ builderFactory.createObjectBuilder()
+ .add("jsonmergepatch",
builderFactory.createObjectBuilder()
+ .add("a", "z")
+ .add("c",
builderFactory.createObjectBuilder()
+ .addNull("f"))
+ .build())
+ .build(),
+ builderFactory.createObjectBuilder()
+ .add("a", "b")
+ .add("c", builderFactory.createObjectBuilder()
+ .add("d", "e")
+ .add("f", "g"))
+ .build()));
+ }
+
+ @Test
+ public void jsonMergeDiff() {
+ assertEquals(
+ builderFactory.createObjectBuilder()
+ .add("a", "z")
+ .add("c", builderFactory.createObjectBuilder()
+ .addNull("f"))
+ .build(),
+ jsonLogic.apply(
+ builderFactory.createObjectBuilder()
+ .add("jsonmergediff",
builderFactory.createObjectBuilder()
+ .add("a", "b")
+ .add("c",
builderFactory.createObjectBuilder()
+ .add("d", "e")
+ .add("f", "g")))
+ .build(),
+ builderFactory.createArrayBuilder()
+ .add(builderFactory.createObjectBuilder()
+ .add("a", "z")
+ .add("c",
builderFactory.createObjectBuilder()
+ .add("d", "e"))
+ .build())
+ .add(builderFactory.createObjectBuilder())
+ .build()));
+ }
+
+ @Test
public void varObjectString() {
assertEquals(Json.createValue("b"), jsonLogic.apply(
builderFactory.createObjectBuilder()
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index e0f75d5..867cec7 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -596,6 +596,8 @@ jsonLogic.registerOperator(
(jsonLogic, config, args) -> log.info(String.valueOf(jsonLogic.apply(config,
args)));
]]></pre>
+Note that by default the set of standard JSON Logic operators is enriched with
JSON-P jsonpatch, json merge diff and json merge patch operators.
+
### OSGi JAX-RS Whiteboard
Though Johnzon artifacts are OSGi bundles to begin with, this module provides
further integration with the [OSGi JAX-RS
Whiteboard](https://osgi.org/specification/osgi.cmpn/7.0.0/service.jaxrs.html)
and [OSGi CDI
Integration](https://osgi.org/specification/osgi.enterprise/7.0.0/service.cdi.html)
specifications.