diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/function/Parameter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/function/Parameter.java index c275fd81..e8eabf97 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/function/Parameter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/function/Parameter.java @@ -10,11 +10,18 @@ public class Parameter { private Path path; private Object cachedValue; private Boolean evaluated = false; + private String json; public Parameter() {} + public Parameter(String json) { + this.json = json; + this.type = ParamType.JSON; + } + public Parameter(Path path) { this.path = path; + this.type = ParamType.PATH; } public Object getCachedValue() { @@ -48,4 +55,12 @@ public class Parameter { public void setPath(Path path) { this.path = path; } + + public String getJson() { + return json; + } + + public void setJson(String json) { + this.json = json; + } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/FunctionPathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/FunctionPathToken.java index 4371993b..5fe851e1 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/FunctionPathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/FunctionPathToken.java @@ -44,7 +44,16 @@ public class FunctionPathToken extends PathToken { if (null != functionParams) { for (Parameter param : functionParams) { if (!param.hasEvaluated()) { - param.setCachedValue(param.getPath().evaluate(ctx.rootDocument(), ctx.rootDocument(), ctx.configuration()).getValue()); + switch (param.getType()) { + case PATH: + param.setCachedValue(param.getPath().evaluate(ctx.rootDocument(), ctx.rootDocument(), ctx.configuration()).getValue()); + param.setEvaluated(true); + break; + case JSON: + param.setCachedValue(ctx.configuration().jsonProvider().parse(param.getJson())); + param.setEvaluated(true); + break; + } } } } 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 bc079bfa..71586743 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 @@ -265,8 +265,9 @@ public class PathCompiler { // Parenthesis starts at 1 since we're marking the start of a function call, the close paren will denote the // last parameter boundary - Integer groupParen = 1, groupBracket = 0, groupBrace = 0; + Integer groupParen = 1, groupBracket = 0, groupBrace = 0, groupQuote = 0; Boolean endOfStream = false; + char priorChar = 0; List parameters = new ArrayList(); StringBuffer parameter = new StringBuffer(); while (path.inBounds(readPosition) && !endOfStream) { @@ -278,7 +279,7 @@ public class PathCompiler { continue; } - if (c == OPEN_BRACE) { + if (c == OPEN_BRACE || isDigit(c) || DOUBLE_QUOTE == c) { type = ParamType.JSON; } else if (isPathContext(c)) { @@ -287,6 +288,14 @@ public class PathCompiler { } switch (c) { + case DOUBLE_QUOTE: + if (priorChar != '\\' && groupQuote > 0) { + groupQuote--; + } + else { + groupQuote++; + } + break; case OPEN_PARENTHESIS: groupParen++; break; @@ -314,24 +323,28 @@ public class PathCompiler { case COMMA: // In this state we've reach the end of a function parameter and we can pass along the parameter string // to the parser - if (null != type && (0 == groupBrace && 0 == groupBracket && ((0 == groupParen && CLOSE_PARENTHESIS == c) || 1 == groupParen))) { - Parameter param = new Parameter(); - param.setType(type); - if (type == ParamType.JSON) { - // parse the json and set the value - param.setCachedValue(parameter.toString()); - param.setEvaluated(true); - } - else if (type == ParamType.PATH) { - LinkedList predicates = new LinkedList(); - PathCompiler compiler = new PathCompiler(parameter.toString(), predicates); - param.setPath(compiler.compile()); - } - parameters.add(param); - parameter.delete(0, parameter.length()); - - type = null; + if ((0 == groupQuote && 0 == groupBrace && 0 == groupBracket && ((0 == groupParen && CLOSE_PARENTHESIS == c) || 1 == groupParen))) { endOfStream = (0 == groupParen); + + if (null != type) { + Parameter param = null; + if (type == ParamType.JSON) { + // parse the json and set the value + param = new Parameter(parameter.toString()); + } else if (type == ParamType.PATH) { + LinkedList predicates = new LinkedList(); + PathCompiler compiler = new PathCompiler(parameter.toString(), predicates); + param = new Parameter(compiler.compile()); + } + if (null != param) { + parameters.add(param); + } else { + // TODO: raise error... + } + parameter.delete(0, parameter.length()); + + type = null; + } } break; } @@ -339,6 +352,7 @@ public class PathCompiler { if (type != null && !(c == COMMA && 0 == groupBrace && 0 == groupBracket && 1 == groupParen)) { parameter.append(c); } + priorChar = c; } path.setPosition(readPosition); return parameters; diff --git a/json-path/src/test/java/com/jayway/jsonpath/internal/function/NestedFunctionTest.java b/json-path/src/test/java/com/jayway/jsonpath/internal/function/NestedFunctionTest.java index 28fb7adb..e078a620 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/internal/function/NestedFunctionTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/internal/function/NestedFunctionTest.java @@ -49,4 +49,9 @@ public class NestedFunctionTest extends BaseFunctionTest { public void testArrayAverageFunctionCallWithParameters() { verifyMathFunction(conf, "$.numbers.sum($.numbers.min(), $.numbers.max())", 66.0); } + + @Test + public void testJsonInnerArgumentArray() { + verifyMathFunction(conf, "$.sum(5, 3, $.numbers.max(), 2)", 20.0); + } }