Skip to content

Commit 51379c6

Browse files
committed
Merge pull request #167 from mgreenwood1001/NestedJsonPathFunctionParameters
Nested json path function parameters
2 parents d3231e7 + e6d2546 commit 51379c6

File tree

19 files changed

+657
-29
lines changed

19 files changed

+657
-29
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.jayway.jsonpath.internal.function;
2+
3+
/**
4+
* Created by mgreenwood on 12/11/15.
5+
*/
6+
public enum ParamType {
7+
JSON,
8+
PATH
9+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.jayway.jsonpath.internal.function;
2+
3+
import com.jayway.jsonpath.internal.Path;
4+
5+
/**
6+
* Created by matt@mjgreenwood.net on 12/10/15.
7+
*/
8+
public class Parameter {
9+
private ParamType type;
10+
private Path path;
11+
private Object cachedValue;
12+
private Boolean evaluated = false;
13+
private String json;
14+
15+
public Parameter() {}
16+
17+
public Parameter(String json) {
18+
this.json = json;
19+
this.type = ParamType.JSON;
20+
}
21+
22+
public Parameter(Path path) {
23+
this.path = path;
24+
this.type = ParamType.PATH;
25+
}
26+
27+
public Object getCachedValue() {
28+
return cachedValue;
29+
}
30+
31+
public void setCachedValue(Object cachedValue) {
32+
this.cachedValue = cachedValue;
33+
}
34+
35+
public Path getPath() {
36+
return path;
37+
}
38+
39+
public void setEvaluated(Boolean evaluated) {
40+
this.evaluated = evaluated;
41+
}
42+
43+
public boolean hasEvaluated() {
44+
return evaluated;
45+
}
46+
47+
public ParamType getType() {
48+
return type;
49+
}
50+
51+
public void setType(ParamType type) {
52+
this.type = type;
53+
}
54+
55+
public void setPath(Path path) {
56+
this.path = path;
57+
}
58+
59+
public String getJson() {
60+
return json;
61+
}
62+
63+
public void setJson(String json) {
64+
this.json = json;
65+
}
66+
}

json-path/src/main/java/com/jayway/jsonpath/internal/function/PassthruPathFunction.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.jayway.jsonpath.internal.EvaluationContext;
44
import com.jayway.jsonpath.internal.PathRef;
55

6+
import java.util.List;
7+
68
/**
79
* Defines the default behavior which is to return the model that is provided as input as output
810
*
@@ -11,7 +13,7 @@
1113
public class PassthruPathFunction implements PathFunction {
1214

1315
@Override
14-
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx) {
16+
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters) {
1517
return model;
1618
}
1719
}

json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.jayway.jsonpath.internal.EvaluationContext;
44
import com.jayway.jsonpath.internal.PathRef;
55

6+
import java.util.List;
7+
68
/**
79
* Defines the pattern by which a function can be executed over the result set in the particular path
810
* being grabbed. The Function's input is the content of the data from the json path selector and its output
@@ -27,7 +29,8 @@ public interface PathFunction {
2729
* @param ctx
2830
* Eval context, state bag used as the path is traversed, maintains the result of executing
2931
*
32+
* @param parameters
3033
* @return
3134
*/
32-
Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx);
35+
Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters);
3336
}

json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.jayway.jsonpath.internal.function;
22

33
import com.jayway.jsonpath.InvalidPathException;
4+
import com.jayway.jsonpath.internal.function.http.HttpLoader;
5+
import com.jayway.jsonpath.internal.function.json.Append;
46
import com.jayway.jsonpath.internal.function.numeric.Average;
57
import com.jayway.jsonpath.internal.function.numeric.Max;
68
import com.jayway.jsonpath.internal.function.numeric.Min;
79
import com.jayway.jsonpath.internal.function.numeric.StandardDeviation;
810
import com.jayway.jsonpath.internal.function.numeric.Sum;
11+
import com.jayway.jsonpath.internal.function.text.Concatenate;
12+
import com.jayway.jsonpath.internal.function.text.Length;
913

1014
import java.util.Collections;
1115
import java.util.HashMap;
@@ -35,9 +39,17 @@ public class PathFunctionFactory {
3539
map.put("min", Min.class);
3640
map.put("max", Max.class);
3741

42+
// Text Functions
43+
map.put("concat", Concatenate.class);
44+
45+
// Network functions
46+
map.put("getjson", HttpLoader.class);
47+
3848
// JSON Entity Functions
3949
map.put("length", Length.class);
4050
map.put("size", Length.class);
51+
map.put("append", Append.class);
52+
4153

4254
FUNCTIONS = Collections.unmodifiableMap(map);
4355
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.jayway.jsonpath.internal.function.http;
2+
3+
import com.jayway.jsonpath.internal.EvaluationContext;
4+
import com.jayway.jsonpath.internal.PathRef;
5+
import com.jayway.jsonpath.internal.function.Parameter;
6+
import com.jayway.jsonpath.internal.function.PathFunction;
7+
8+
import java.io.BufferedReader;
9+
import java.io.IOException;
10+
import java.io.InputStreamReader;
11+
import java.net.HttpURLConnection;
12+
import java.net.MalformedURLException;
13+
import java.net.ProtocolException;
14+
import java.net.URL;
15+
import java.util.List;
16+
17+
/**
18+
* Dirt simple http get method just to demo URL loading
19+
*
20+
* Created by mgreenwood on 12/11/15.
21+
*/
22+
public class HttpLoader implements PathFunction {
23+
@Override
24+
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters) {
25+
if (parameters != null && parameters.size() == 1) {
26+
try {
27+
URL url = new URL(parameters.get(0).getCachedValue().toString());
28+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
29+
conn.setRequestMethod("GET");
30+
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
31+
String line;
32+
StringBuffer result = new StringBuffer();
33+
while ((line = rd.readLine()) != null) {
34+
result.append(line);
35+
}
36+
rd.close();
37+
Object jsonResult = ctx.configuration().jsonProvider().parse(result.toString());
38+
return jsonResult;
39+
} catch (ProtocolException e) {
40+
e.printStackTrace();
41+
} catch (MalformedURLException e) {
42+
e.printStackTrace();
43+
} catch (IOException e) {
44+
e.printStackTrace();
45+
}
46+
}
47+
return null;
48+
}
49+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.jayway.jsonpath.internal.function.json;
2+
3+
import com.jayway.jsonpath.internal.EvaluationContext;
4+
import com.jayway.jsonpath.internal.PathRef;
5+
import com.jayway.jsonpath.internal.function.Parameter;
6+
import com.jayway.jsonpath.internal.function.PathFunction;
7+
import com.jayway.jsonpath.spi.json.JsonProvider;
8+
9+
import java.util.List;
10+
11+
/**
12+
* Appends JSON structure to the current document so that you can utilize the JSON added thru another function call.
13+
* If there are multiple parameters then this function call will add each element that is json to the structure
14+
*
15+
* Created by mgreenwood on 12/14/15.
16+
*/
17+
public class Append implements PathFunction {
18+
@Override
19+
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters) {
20+
JsonProvider jsonProvider = ctx.configuration().jsonProvider();
21+
if (parameters != null && parameters.size() > 0) {
22+
for (Parameter param : parameters) {
23+
if (jsonProvider.isArray(model)) {
24+
int len = jsonProvider.length(model);
25+
jsonProvider.setArrayIndex(model, len, param.getCachedValue());
26+
}
27+
}
28+
}
29+
return model;
30+
}
31+
}

json-path/src/main/java/com/jayway/jsonpath/internal/function/numeric/AbstractAggregation.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.jayway.jsonpath.internal.function.numeric;
22

3+
import com.jayway.jsonpath.JsonPathException;
34
import com.jayway.jsonpath.internal.EvaluationContext;
45
import com.jayway.jsonpath.internal.PathRef;
6+
import com.jayway.jsonpath.internal.function.Parameter;
57
import com.jayway.jsonpath.internal.function.PathFunction;
68

9+
import java.util.List;
10+
711
/**
812
* Defines the pattern for processing numerical values via an abstract implementation that iterates over the collection
913
* of JSONArray entities and verifies that each is a numerical value and then passes that along the abstract methods
@@ -30,18 +34,31 @@ public abstract class AbstractAggregation implements PathFunction {
3034
protected abstract Number getValue();
3135

3236
@Override
33-
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx) {
37+
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters) {
38+
int count = 0;
3439
if(ctx.configuration().jsonProvider().isArray(model)){
3540

3641
Iterable<?> objects = ctx.configuration().jsonProvider().toIterable(model);
3742
for (Object obj : objects) {
3843
if (obj instanceof Number) {
3944
Number value = (Number) obj;
45+
count++;
46+
next(value);
47+
}
48+
}
49+
}
50+
if (parameters != null) {
51+
for (Parameter param : parameters) {
52+
if (param.getCachedValue() instanceof Number) {
53+
Number value = (Number)param.getCachedValue();
54+
count++;
4055
next(value);
4156
}
4257
}
58+
}
59+
if (count != 0) {
4360
return getValue();
4461
}
45-
return null;
62+
throw new JsonPathException("Aggregation function attempted to calculate value using empty array");
4663
}
4764
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.jayway.jsonpath.internal.function.text;
2+
3+
import com.jayway.jsonpath.internal.EvaluationContext;
4+
import com.jayway.jsonpath.internal.PathRef;
5+
import com.jayway.jsonpath.internal.function.Parameter;
6+
import com.jayway.jsonpath.internal.function.PathFunction;
7+
8+
import java.util.List;
9+
10+
/**
11+
* String function concat - simple takes a list of arguments and/or an array and concatenates them together to form a
12+
* single string
13+
*
14+
* Created by mgreenwood on 12/11/15.
15+
*/
16+
public class Concatenate implements PathFunction {
17+
@Override
18+
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters) {
19+
StringBuffer result = new StringBuffer();
20+
if(ctx.configuration().jsonProvider().isArray(model)){
21+
Iterable<?> objects = ctx.configuration().jsonProvider().toIterable(model);
22+
for (Object obj : objects) {
23+
if (obj instanceof String) {
24+
result.append(obj.toString());
25+
}
26+
}
27+
}
28+
if (parameters != null) {
29+
for (Parameter param : parameters) {
30+
if (param.getCachedValue() != null) {
31+
result.append(param.getCachedValue().toString());
32+
}
33+
}
34+
}
35+
return result.toString();
36+
}
37+
}

json-path/src/main/java/com/jayway/jsonpath/internal/function/Length.java renamed to json-path/src/main/java/com/jayway/jsonpath/internal/function/text/Length.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
package com.jayway.jsonpath.internal.function;
1+
package com.jayway.jsonpath.internal.function.text;
22

33
import com.jayway.jsonpath.internal.EvaluationContext;
44
import com.jayway.jsonpath.internal.PathRef;
5+
import com.jayway.jsonpath.internal.function.Parameter;
6+
import com.jayway.jsonpath.internal.function.PathFunction;
7+
8+
import java.util.List;
59

610
/**
711
* Provides the length of a JSONArray Object
@@ -11,7 +15,7 @@
1115
public class Length implements PathFunction {
1216

1317
@Override
14-
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx) {
18+
public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List<Parameter> parameters) {
1519
if(ctx.configuration().jsonProvider().isArray(model)){
1620
return ctx.configuration().jsonProvider().length(model);
1721
} else if(ctx.configuration().jsonProvider().isMap(model)){

0 commit comments

Comments
 (0)