Skip to content

Commit 8512498

Browse files
author
Greenwood
committed
Issue json-path#191 is a bug - supports result set functions via patterns such as $.max($..allTheNumberThings)
$.max($.foo, $.bar) is already supported - consiquently $.max($..allTheNumberThings) should also work.
1 parent efdab97 commit 8512498

File tree

6 files changed

+1371
-15
lines changed

6 files changed

+1371
-15
lines changed

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

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

3+
import com.jayway.jsonpath.internal.EvaluationContext;
34
import com.jayway.jsonpath.internal.Path;
45
import com.jayway.jsonpath.internal.function.latebinding.ILateBindingValue;
5-
import com.jayway.jsonpath.internal.function.latebinding.PathLateBindingValue;
6+
7+
import java.util.ArrayList;
8+
import java.util.Collection;
9+
import java.util.List;
610

711
/**
8-
* Created by matt@mjgreenwood.net on 12/10/15.
12+
* Defines a parameter as passed to a function with late binding support for lazy evaluation.
913
*/
1014
public class Parameter {
1115
private ParamType type;
@@ -65,4 +69,63 @@ public String getJson() {
6569
public void setJson(String json) {
6670
this.json = json;
6771
}
72+
73+
/**
74+
* Translate the collection of parameters into a collection of values of type T.
75+
*
76+
* @param type
77+
* The type to translate the collection into.
78+
*
79+
* @param ctx
80+
* Context.
81+
*
82+
* @param parameters
83+
* Collection of parameters.
84+
*
85+
* @param <T>
86+
* Type T returned as a List of T.
87+
*
88+
* @return
89+
* List of T either empty or containing contents.
90+
*/
91+
public static <T> List<T> toList(final Class<T> type, final EvaluationContext ctx, final List<Parameter> parameters) {
92+
List<T> values = new ArrayList();
93+
if (null != parameters) {
94+
for (Parameter param : parameters) {
95+
consume(type, ctx, values, param.getValue());
96+
}
97+
}
98+
return values;
99+
}
100+
101+
/**
102+
* Either consume the object as an array and add each element to the collection, or alternatively add each element
103+
*
104+
* @param expectedType
105+
* the expected class type to consume, if null or not of this type the element is not added to the array.
106+
*
107+
* @param ctx
108+
* the JSON context to determine if this is an array or value.
109+
*
110+
* @param collection
111+
* The collection to append into.
112+
*
113+
* @param value
114+
* The value to evaluate.
115+
*/
116+
public static void consume(Class expectedType, EvaluationContext ctx, Collection collection, Object value) {
117+
if (ctx.configuration().jsonProvider().isArray(value)) {
118+
for (Object o : ctx.configuration().jsonProvider().toIterable(value)) {
119+
if (o != null && expectedType.isAssignableFrom(o.getClass())) {
120+
collection.add(o);
121+
} else if (o != null && expectedType == String.class) {
122+
collection.add(o.toString());
123+
}
124+
}
125+
} else {
126+
if (value != null && expectedType.isAssignableFrom(value.getClass())) {
127+
collection.add(value);
128+
}
129+
}
130+
}
68131
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
* Leverages the function's name in order to determine which function to execute which is maintained internally
2222
* here via a static map
2323
*
24-
* Created by mattg on 6/27/15.
2524
*/
2625
public class PathFunctionFactory {
2726

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,9 @@ public Object invoke(String currentPath, PathRef parent, Object model, Evaluatio
4848
}
4949
}
5050
if (parameters != null) {
51-
for (Parameter param : parameters) {
52-
Object value = param.getValue();
53-
if (null != value && value instanceof Number) {
54-
count++;
55-
next((Number)value);
56-
}
51+
for (Number value : Parameter.toList(Number.class, ctx, parameters)) {
52+
count++;
53+
next(value);
5754
}
5855
}
5956
if (count != 0) {

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
* String function concat - simple takes a list of arguments and/or an array and concatenates them together to form a
1212
* single string
1313
*
14-
* Created by mgreenwood on 12/11/15.
1514
*/
1615
public class Concatenate implements PathFunction {
1716
@Override
@@ -26,11 +25,8 @@ public Object invoke(String currentPath, PathRef parent, Object model, Evaluatio
2625
}
2726
}
2827
if (parameters != null) {
29-
for (Parameter param : parameters) {
30-
Object value = param.getValue();
31-
if (value != null) {
32-
result.append(value.toString());
33-
}
28+
for (String value : Parameter.toList(String.class, ctx, parameters)) {
29+
result.append(value);
3430
}
3531
}
3632
return result.toString();
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.jayway.jsonpath.internal.function;
2+
3+
import com.jayway.jsonpath.Configuration;
4+
import com.jayway.jsonpath.Configurations;
5+
import com.jayway.jsonpath.JsonPath;
6+
import org.junit.Test;
7+
8+
import java.io.InputStream;
9+
10+
import static org.junit.Assert.assertEquals;
11+
12+
/**
13+
* TDD for Issue 191
14+
*
15+
* Shows aggregation across fields rather than within a single entity.
16+
*
17+
*/
18+
public class Issue191 extends com.jayway.jsonpath.internal.function.BaseFunctionTest {
19+
20+
private Configuration conf = Configurations.GSON_CONFIGURATION;
21+
22+
@Test
23+
public void testResultSetNumericComputation() {
24+
InputStream stream = ClassLoader.getSystemResourceAsStream("issue_191.json");
25+
Long value = JsonPath.parse(stream).read("$.max($..timestamp)", Long.class);
26+
assertEquals("Expected the max function to consume the aggregation parameters and calculate the max over the result set",
27+
Long.valueOf(1427310341), value);
28+
}
29+
30+
@Test
31+
public void testConcatResultSet() {
32+
InputStream stream = ClassLoader.getSystemResourceAsStream("issue_191.json");
33+
String concatResult = JsonPath.parse(stream).read("$.concat($..state)", String.class);
34+
assertEquals("Expected a string length to be a concat of all of the states", concatResult.length(), 806);
35+
}
36+
37+
@Test
38+
public void testConcatWithNumericValueAsString() {
39+
InputStream stream = ClassLoader.getSystemResourceAsStream("issue_191.json");
40+
String concatResult = JsonPath.parse(stream).read("$.concat($..cpus)", String.class);
41+
assertEquals("Expected a string length to be a concat of all of the cpus", concatResult.length(), 489);
42+
}
43+
}

0 commit comments

Comments
 (0)