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 2fcd3a33..bfb489b9 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 @@ -9,6 +9,7 @@ import com.jayway.jsonpath.internal.function.numeric.Min; import com.jayway.jsonpath.internal.function.numeric.StandardDeviation; import com.jayway.jsonpath.internal.function.numeric.Sum; import com.jayway.jsonpath.internal.function.text.Concatenate; +import com.jayway.jsonpath.internal.function.text.Join; import com.jayway.jsonpath.internal.function.text.Length; import java.util.Collections; @@ -40,6 +41,7 @@ public class PathFunctionFactory { // Text Functions map.put("concat", Concatenate.class); + map.put("join", Join.class); // JSON Entity Functions map.put(Length.TOKEN_NAME, Length.class); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/function/text/Join.java b/json-path/src/main/java/com/jayway/jsonpath/internal/function/text/Join.java new file mode 100644 index 00000000..8fcb219c --- /dev/null +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/function/text/Join.java @@ -0,0 +1,44 @@ +package com.jayway.jsonpath.internal.function.text; + +import com.jayway.jsonpath.JsonPathException; +import com.jayway.jsonpath.internal.EvaluationContext; +import com.jayway.jsonpath.internal.PathRef; +import com.jayway.jsonpath.internal.function.Parameter; +import com.jayway.jsonpath.internal.function.PathFunction; + +import java.util.Iterator; +import java.util.List; + +/** + * Provides the join of a JSONArray Object + * + * Created by fbrissi on 6/26/15. + */ +public class Join implements PathFunction { + + @Override + public Object invoke(String currentPath, PathRef parent, Object model, EvaluationContext ctx, List parameters) { + StringBuilder builder = new StringBuilder(); + Parameter path = null != parameters && parameters.size() > 1 ? parameters.get(1) : null; + String delimiter = null != parameters && parameters.size() > 0 ? parameters.get(0).getValue().toString() : ","; + if (ctx.configuration().jsonProvider().isArray(model)) { + Iterator iterator = ctx.configuration().jsonProvider().toIterable(model).iterator(); + while (iterator.hasNext()) { + Object innerModel = null == path ? iterator.next() + : path.getPath().evaluate(iterator.next(), model, ctx.configuration()).getValue(); + if (ctx.configuration().jsonProvider().isArray(innerModel)) { + Iterable iterable = ctx.configuration().jsonProvider().toIterable(innerModel); + builder.append(iterable.iterator().next().toString()); + } else { + builder.append(innerModel.toString()); + } + if (iterator.hasNext()) { + builder.append(delimiter); + } + } + return builder.toString(); + } + throw new JsonPathException(String.format("join operation cannot be applied to %s", model.getClass())); + } + +} diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java index 72f68126..22942dd7 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java @@ -383,7 +383,7 @@ public class PathCompiler { break; } - if (type != null && !(c == COMMA && 0 == groupBrace && 0 == groupBracket && 1 == groupParen)) { + if (type != null && !(c == COMMA && 0 == groupBrace && 0 == groupBracket && 1 == groupParen && 0 == groupQuote)) { parameter.append(c); } priorChar = c; @@ -612,7 +612,7 @@ public class PathCompiler { inProperty = true; lastSignificantWasComma = false; } - } else if (c == COMMA && !inProperty) { + } else if (c == COMMA && !inProperty) { if (lastSignificantWasComma){ fail("Found empty property at index "+readPosition); } diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java index b26a2b8f..1ad991f3 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/BaseFunctionTest.java @@ -14,6 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class BaseFunctionTest { protected static final String NUMBER_SERIES = "{\"empty\": [], \"numbers\" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}"; protected static final String TEXT_SERIES = "{\"urls\": [\"http://api.worldbank.org/countries/all/?format=json\", \"http://api.worldbank.org/countries/all/?format=json\"], \"text\" : [ \"a\", \"b\", \"c\", \"d\", \"e\", \"f\" ]}"; + protected static final String TEXT_JOIN_SERIES = "{\"urls\": [\"http://api.worldbank.org/countries/all/?format=json\", \"http://api.worldbank.org/countries/all/?format=json\"], \"text\" : [ { \"value\": \"a\" }, { \"value\": \"b\" }, { \"value\": \"c\" }, { \"value\": \"d\" }, { \"value\": \"e\" }, { \"value\": \"f\" } ]}"; protected static final String TEXT_AND_NUMBER_SERIES = "{\"text\" : [ \"a\", \"b\", \"c\", \"d\", \"e\", \"f\" ], \"numbers\" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}"; /** diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/JSONEntityPathFunctionTest.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/JSONEntityPathFunctionTest.java index 3017cbb6..e7c74f20 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/internal/function/JSONEntityPathFunctionTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/JSONEntityPathFunctionTest.java @@ -60,6 +60,15 @@ public class JSONEntityPathFunctionTest extends BaseFunctionTest { verifyFunction(conf, "$['text'].length()", TEXT_SERIES, 6); verifyFunction(conf, "$['text'].size()", TEXT_SERIES, 6); } + + @Test + public void testJoinOfTextArray() { + verifyFunction(conf, "$.text.join()", TEXT_SERIES, "a,b,c,d,e,f"); + verifyFunction(conf, "$.text.join(\", \")", TEXT_SERIES, "a, b, c, d, e, f"); + verifyFunction(conf, "$.text.join(\", \", @..value)", TEXT_JOIN_SERIES, "a, b, c, d, e, f"); + verifyFunction(conf, "$['text'].join(\"|\", @..value)", TEXT_JOIN_SERIES, "a|b|c|d|e|f"); + } + @Test public void testLengthOfNumberArray() { // The length of JSONArray is an integer