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 <rmannibu...@gmail.com>
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.

Reply via email to