Browse Source

Issue #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.
pull/377/head
Greenwood 7 years ago
parent
commit
851249861e
  1. 67
      json-path/src/main/java/com/jayway/jsonpath/internal/function/Parameter.java
  2. 1
      json-path/src/main/java/com/jayway/jsonpath/internal/function/PathFunctionFactory.java
  3. 9
      json-path/src/main/java/com/jayway/jsonpath/internal/function/numeric/AbstractAggregation.java
  4. 8
      json-path/src/main/java/com/jayway/jsonpath/internal/function/text/Concatenate.java
  5. 43
      json-path/src/test/java/com/jayway/jsonpath/internal/function/Issue191.java
  6. 1258
      json-path/src/test/resources/issue_191.json

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

@ -1,11 +1,15 @@
package com.jayway.jsonpath.internal.function;
import com.jayway.jsonpath.internal.EvaluationContext;
import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.function.latebinding.ILateBindingValue;
import com.jayway.jsonpath.internal.function.latebinding.PathLateBindingValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Created by matt@mjgreenwood.net on 12/10/15.
* Defines a parameter as passed to a function with late binding support for lazy evaluation.
*/
public class Parameter {
private ParamType type;
@ -65,4 +69,63 @@ public class Parameter {
public void setJson(String json) {
this.json = json;
}
/**
* Translate the collection of parameters into a collection of values of type T.
*
* @param type
* The type to translate the collection into.
*
* @param ctx
* Context.
*
* @param parameters
* Collection of parameters.
*
* @param <T>
* Type T returned as a List of T.
*
* @return
* List of T either empty or containing contents.
*/
public static <T> List<T> toList(final Class<T> type, final EvaluationContext ctx, final List<Parameter> parameters) {
List<T> values = new ArrayList();
if (null != parameters) {
for (Parameter param : parameters) {
consume(type, ctx, values, param.getValue());
}
}
return values;
}
/**
* Either consume the object as an array and add each element to the collection, or alternatively add each element
*
* @param expectedType
* the expected class type to consume, if null or not of this type the element is not added to the array.
*
* @param ctx
* the JSON context to determine if this is an array or value.
*
* @param collection
* The collection to append into.
*
* @param value
* The value to evaluate.
*/
public static void consume(Class expectedType, EvaluationContext ctx, Collection collection, Object value) {
if (ctx.configuration().jsonProvider().isArray(value)) {
for (Object o : ctx.configuration().jsonProvider().toIterable(value)) {
if (o != null && expectedType.isAssignableFrom(o.getClass())) {
collection.add(o);
} else if (o != null && expectedType == String.class) {
collection.add(o.toString());
}
}
} else {
if (value != null && expectedType.isAssignableFrom(value.getClass())) {
collection.add(value);
}
}
}
}

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

@ -21,7 +21,6 @@ import java.util.Map;
* Leverages the function's name in order to determine which function to execute which is maintained internally
* here via a static map
*
* Created by mattg on 6/27/15.
*/
public class PathFunctionFactory {

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

@ -48,12 +48,9 @@ public abstract class AbstractAggregation implements PathFunction {
}
}
if (parameters != null) {
for (Parameter param : parameters) {
Object value = param.getValue();
if (null != value && value instanceof Number) {
count++;
next((Number)value);
}
for (Number value : Parameter.toList(Number.class, ctx, parameters)) {
count++;
next(value);
}
}
if (count != 0) {

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

@ -11,7 +11,6 @@ import java.util.List;
* String function concat - simple takes a list of arguments and/or an array and concatenates them together to form a
* single string
*
* Created by mgreenwood on 12/11/15.
*/
public class Concatenate implements PathFunction {
@Override
@ -26,11 +25,8 @@ public class Concatenate implements PathFunction {
}
}
if (parameters != null) {
for (Parameter param : parameters) {
Object value = param.getValue();
if (value != null) {
result.append(value.toString());
}
for (String value : Parameter.toList(String.class, ctx, parameters)) {
result.append(value);
}
}
return result.toString();

43
json-path/src/test/java/com/jayway/jsonpath/internal/function/Issue191.java

@ -0,0 +1,43 @@
package com.jayway.jsonpath.internal.function;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Configurations;
import com.jayway.jsonpath.JsonPath;
import org.junit.Test;
import java.io.InputStream;
import static org.junit.Assert.assertEquals;
/**
* TDD for Issue 191
*
* Shows aggregation across fields rather than within a single entity.
*
*/
public class Issue191 extends com.jayway.jsonpath.internal.function.BaseFunctionTest {
private Configuration conf = Configurations.GSON_CONFIGURATION;
@Test
public void testResultSetNumericComputation() {
InputStream stream = ClassLoader.getSystemResourceAsStream("issue_191.json");
Long value = JsonPath.parse(stream).read("$.max($..timestamp)", Long.class);
assertEquals("Expected the max function to consume the aggregation parameters and calculate the max over the result set",
Long.valueOf(1427310341), value);
}
@Test
public void testConcatResultSet() {
InputStream stream = ClassLoader.getSystemResourceAsStream("issue_191.json");
String concatResult = JsonPath.parse(stream).read("$.concat($..state)", String.class);
assertEquals("Expected a string length to be a concat of all of the states", concatResult.length(), 806);
}
@Test
public void testConcatWithNumericValueAsString() {
InputStream stream = ClassLoader.getSystemResourceAsStream("issue_191.json");
String concatResult = JsonPath.parse(stream).read("$.concat($..cpus)", String.class);
assertEquals("Expected a string length to be a concat of all of the cpus", concatResult.length(), 489);
}
}

1258
json-path/src/test/resources/issue_191.json

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save