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 3a31151f..a9f7df5f 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 @@ -14,7 +14,7 @@ import com.jayway.jsonpath.internal.function.sequence.Last; import com.jayway.jsonpath.internal.function.text.Concatenate; import com.jayway.jsonpath.internal.function.text.Length; -import java.util.Collections; +import java.io.InvalidClassException; import java.util.HashMap; import java.util.Map; @@ -28,7 +28,7 @@ import java.util.Map; */ 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 +56,7 @@ public class PathFunctionFactory { map.put("index", Index.class); - FUNCTIONS = Collections.unmodifiableMap(map); + FUNCTIONS = map; } /** @@ -85,4 +85,14 @@ public class PathFunctionFactory { } } } + + 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"); + } + 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 00000000..3c9593ca --- /dev/null +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/CustomFunctionTest.java @@ -0,0 +1,37 @@ +package com.jayway.jsonpath.internal.function; + +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.Configurations; +import com.jayway.jsonpath.InvalidPathException; +import org.junit.jupiter.api.Test; + +import java.io.InvalidClassException; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +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"); + } + + @Test + void testAddExistentFunction(){ + assertThrows(InvalidPathException.class, () -> PathFunctionFactory.addCustomFunction("avg", + ToUpperCase.class)); + } +} 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 00000000..6a7c4c1c --- /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(); + } +}