From 3cb3d9024efcfb5f76606be5883d2395756fe92d Mon Sep 17 00:00:00 2001 From: lunascim Date: Tue, 2 Jul 2024 07:11:26 +0100 Subject: [PATCH 1/2] Implemented the possibility to add custom path functions --- .../function/PathFunctionFactory.java | 13 ++++++-- .../internal/function/CustomFunctionTest.java | 33 +++++++++++++++++++ .../internal/function/ToUpperCase.java | 14 ++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java create mode 100644 json-path/src/test/java/com/jayway/jsonpath/internal/function/ToUpperCase.java diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java b/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java index 3a31151f2..c84a6c22b 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java @@ -1,6 +1,7 @@ package com.jayway.jsonpath.internal.function; import com.jayway.jsonpath.InvalidPathException; +import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.function.json.Append; import com.jayway.jsonpath.internal.function.json.KeySetFunction; import com.jayway.jsonpath.internal.function.numeric.Average; @@ -14,6 +15,7 @@ import com.jayway.jsonpath.internal.function.text.Concatenate; import com.jayway.jsonpath.internal.function.text.Length; +import java.io.InvalidClassException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -28,7 +30,7 @@ */ public class PathFunctionFactory { - public static final Map FUNCTIONS; + private static final Map FUNCTIONS; static { // New functions should be added here and ensure the name is not overridden @@ -56,7 +58,7 @@ public class PathFunctionFactory { map.put("index", Index.class); - FUNCTIONS = Collections.unmodifiableMap(map); + FUNCTIONS = map; } /** @@ -85,4 +87,11 @@ public static PathFunction newFunction(String name) throws InvalidPathException } } } + + public static void addCustomFunction(String name,Class function) throws InvalidClassException { + if (!PathFunction.class.isAssignableFrom(function)){ + throw new InvalidClassException("Function with name: " + name + "must be a instance of PathFunction class"); + } + FUNCTIONS.put(name,function); + } } diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java new file mode 100644 index 000000000..1d1dd1cc2 --- /dev/null +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java @@ -0,0 +1,33 @@ +package com.jayway.jsonpath.internal.function; + +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.Configurations; +import com.jayway.jsonpath.internal.EvaluationContext; +import com.jayway.jsonpath.internal.PathRef; +import org.junit.jupiter.api.Test; + +import java.io.InvalidClassException; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class CustomFunctionTest extends BaseFunctionTest { + + private Configuration conf = Configurations.JSON_SMART_CONFIGURATION; + + public class InvalidFunction { + + } + @Test + void testAddInvalidFunction(){ + assertThrows(InvalidClassException.class, () -> PathFunctionFactory.addCustomFunction("invalid", + InvalidFunction.class)); + } + + @Test + void testAddValidFunction(){ + assertDoesNotThrow(()->PathFunctionFactory.addCustomFunction("toUpperCase",ToUpperCase.class)); + verifyTextFunction(conf,"$['text'][0].toUpperCase()","A"); + } +} diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/ToUpperCase.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/ToUpperCase.java new file mode 100644 index 000000000..6a7c4c1ce --- /dev/null +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/ToUpperCase.java @@ -0,0 +1,14 @@ +package com.jayway.jsonpath.internal.function; + +import com.jayway.jsonpath.internal.EvaluationContext; +import com.jayway.jsonpath.internal.PathRef; + +import java.util.List; + +public class ToUpperCase implements PathFunction{ + @Override + public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, + List parameters) { + return ((String) model).toUpperCase(); + } +} From d943ebca3225d3b63d285a9e339b71f14071afd6 Mon Sep 17 00:00:00 2001 From: lunascim Date: Mon, 3 Feb 2025 16:15:33 +0000 Subject: [PATCH 2/2] Added the validation to avoid override existent function. --- .../internal/function/PathFunctionFactory.java | 5 +++-- .../internal/function/CustomFunctionTest.java | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java b/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java index c84a6c22b..a9f7df5f1 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java @@ -1,7 +1,6 @@ package com.jayway.jsonpath.internal.function; import com.jayway.jsonpath.InvalidPathException; -import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.function.json.Append; import com.jayway.jsonpath.internal.function.json.KeySetFunction; import com.jayway.jsonpath.internal.function.numeric.Average; @@ -16,7 +15,6 @@ import com.jayway.jsonpath.internal.function.text.Length; import java.io.InvalidClassException; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -89,6 +87,9 @@ public static PathFunction newFunction(String name) throws InvalidPathException } public static void addCustomFunction(String name,Class function) throws InvalidClassException { + if(FUNCTIONS.containsKey(name)){ + throw new InvalidPathException("Function with name: " + name + " already exists"); + } if (!PathFunction.class.isAssignableFrom(function)){ throw new InvalidClassException("Function with name: " + name + "must be a instance of PathFunction class"); } diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java index 1d1dd1cc2..3c9593ca9 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java @@ -2,17 +2,15 @@ import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.Configurations; -import com.jayway.jsonpath.internal.EvaluationContext; -import com.jayway.jsonpath.internal.PathRef; +import com.jayway.jsonpath.InvalidPathException; import org.junit.jupiter.api.Test; import java.io.InvalidClassException; -import java.util.List; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; -public class CustomFunctionTest extends BaseFunctionTest { +class CustomFunctionTest extends BaseFunctionTest { private Configuration conf = Configurations.JSON_SMART_CONFIGURATION; @@ -30,4 +28,10 @@ void testAddValidFunction(){ assertDoesNotThrow(()->PathFunctionFactory.addCustomFunction("toUpperCase",ToUpperCase.class)); verifyTextFunction(conf,"$['text'][0].toUpperCase()","A"); } + + @Test + void testAddExistentFunction(){ + assertThrows(InvalidPathException.class, () -> PathFunctionFactory.addCustomFunction("avg", + ToUpperCase.class)); + } }