-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Adding support for custom path functions #286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.jayway.jsonpath.internal.function; | ||
|
|
||
| import com.jayway.jsonpath.InvalidPathException; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public interface JsonPathFunctionFactory { | ||
| /** | ||
| * Returns the function by name or throws InvalidPathException if function not found. | ||
| * | ||
| * @see #FUNCTIONS | ||
| * @see PathFunction | ||
| * | ||
| * @param name | ||
| * The name of the function | ||
| * | ||
| * @return | ||
| * The implementation of a function | ||
| * | ||
| * @throws InvalidPathException | ||
| */ | ||
| PathFunction newFunction(final String name) throws InvalidPathException; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package com.jayway.jsonpath.internal.function; | ||
|
|
||
| import com.jayway.jsonpath.InvalidPathException; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| public class MapJsonPathFunctionFactory implements JsonPathFunctionFactory { | ||
|
|
||
| private final Map<String, Class<? extends PathFunction>> pathFunctionMap; | ||
|
|
||
| public MapJsonPathFunctionFactory( | ||
| final Map<String, Class<? extends PathFunction>> pathFunctionMap) { | ||
|
|
||
| this.pathFunctionMap = pathFunctionMap; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest you clone the list here so that modifications to the original map don't affect the factory. |
||
| } | ||
|
|
||
| @Override | ||
| public PathFunction newFunction(final String name) throws InvalidPathException { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I question whether PathFunction as an interface is an appropriate expression for a user facing function feature - there's some nuance to know in what context the function is being invoked that is internal state of the JsonPath library. Breaking apart the types of PathFunctions (aggregations vs straight calculations) might be a good way to tease apart the interface into something more meaningful for the end-user. Also, does the function need to take parameters -- can a sub-select be a parameter to the function - expressing that in a more general way such that the consumer doesn't need to grok the internals of JsonPath would be ideal. Certainly keep this method as all interfaces/implementations are a PathFunction, but I think you might want to introduce additional factory methods for aggregation vs straight calculation and then abstract away the nuance of accepting parameters. |
||
| Class functionClazz = pathFunctionMap.get(name); | ||
| if(functionClazz == null){ | ||
| throw new InvalidPathException("Function with name: " + name + " does not exists."); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be "does not exist." |
||
| } else { | ||
| try { | ||
| return (PathFunction)functionClazz.newInstance(); | ||
| } catch (Exception e) { | ||
| throw new InvalidPathException("Function of name: " + name + " cannot be created", e); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,11 +25,11 @@ | |
| */ | ||
| public class PathFunctionFactory { | ||
|
|
||
| public static final Map<String, Class> FUNCTIONS; | ||
| public static final Map<String, Class<? extends PathFunction>> FUNCTIONS; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe move the value/initialization to the |
||
|
|
||
| static { | ||
| // New functions should be added here and ensure the name is not overridden | ||
| Map<String, Class> map = new HashMap<String, Class>(); | ||
| Map<String, Class<? extends PathFunction>> map = new HashMap<String, Class<? extends PathFunction>>(); | ||
|
|
||
| // Math Functions | ||
| map.put("avg", Average.class); | ||
|
|
@@ -64,16 +64,8 @@ public class PathFunctionFactory { | |
| * | ||
| * @throws InvalidPathException | ||
| */ | ||
| @Deprecated | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should deprecate the whole class |
||
| public static PathFunction newFunction(String name) throws InvalidPathException { | ||
| Class functionClazz = FUNCTIONS.get(name); | ||
| if(functionClazz == null){ | ||
| throw new InvalidPathException("Function with name: " + name + " does not exists."); | ||
| } else { | ||
| try { | ||
| return (PathFunction)functionClazz.newInstance(); | ||
| } catch (Exception e) { | ||
| throw new InvalidPathException("Function of name: " + name + " cannot be created", e); | ||
| } | ||
| } | ||
| return new MapJsonPathFunctionFactory(FUNCTIONS).newFunction(name); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be moved to a package within
com.jayway.jsonpath.spi, along with the implementation class.