Browse Source

working version with JSON + path expressions - need to handle error cases with tests

pull/167/head
Matthew J Greenwood 9 years ago
parent
commit
f932aaf22f
  1. 15
      json-path/src/main/java/com/jayway/jsonpath/internal/function/Parameter.java
  2. 9
      json-path/src/main/java/com/jayway/jsonpath/internal/path/FunctionPathToken.java
  3. 36
      json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java
  4. 5
      json-path/src/test/java/com/jayway/jsonpath/internal/function/NestedFunctionTest.java

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

@ -10,11 +10,18 @@ public class Parameter {
private Path path; private Path path;
private Object cachedValue; private Object cachedValue;
private Boolean evaluated = false; private Boolean evaluated = false;
private String json;
public Parameter() {} public Parameter() {}
public Parameter(String json) {
this.json = json;
this.type = ParamType.JSON;
}
public Parameter(Path path) { public Parameter(Path path) {
this.path = path; this.path = path;
this.type = ParamType.PATH;
} }
public Object getCachedValue() { public Object getCachedValue() {
@ -48,4 +55,12 @@ public class Parameter {
public void setPath(Path path) { public void setPath(Path path) {
this.path = path; this.path = path;
} }
public String getJson() {
return json;
}
public void setJson(String json) {
this.json = json;
}
} }

9
json-path/src/main/java/com/jayway/jsonpath/internal/path/FunctionPathToken.java

@ -44,7 +44,16 @@ public class FunctionPathToken extends PathToken {
if (null != functionParams) { if (null != functionParams) {
for (Parameter param : functionParams) { for (Parameter param : functionParams) {
if (!param.hasEvaluated()) { if (!param.hasEvaluated()) {
switch (param.getType()) {
case PATH:
param.setCachedValue(param.getPath().evaluate(ctx.rootDocument(), ctx.rootDocument(), ctx.configuration()).getValue()); 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;
}
} }
} }
} }

36
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 // Parenthesis starts at 1 since we're marking the start of a function call, the close paren will denote the
// last parameter boundary // last parameter boundary
Integer groupParen = 1, groupBracket = 0, groupBrace = 0; Integer groupParen = 1, groupBracket = 0, groupBrace = 0, groupQuote = 0;
Boolean endOfStream = false; Boolean endOfStream = false;
char priorChar = 0;
List<Parameter> parameters = new ArrayList<Parameter>(); List<Parameter> parameters = new ArrayList<Parameter>();
StringBuffer parameter = new StringBuffer(); StringBuffer parameter = new StringBuffer();
while (path.inBounds(readPosition) && !endOfStream) { while (path.inBounds(readPosition) && !endOfStream) {
@ -278,7 +279,7 @@ public class PathCompiler {
continue; continue;
} }
if (c == OPEN_BRACE) { if (c == OPEN_BRACE || isDigit(c) || DOUBLE_QUOTE == c) {
type = ParamType.JSON; type = ParamType.JSON;
} }
else if (isPathContext(c)) { else if (isPathContext(c)) {
@ -287,6 +288,14 @@ public class PathCompiler {
} }
switch (c) { switch (c) {
case DOUBLE_QUOTE:
if (priorChar != '\\' && groupQuote > 0) {
groupQuote--;
}
else {
groupQuote++;
}
break;
case OPEN_PARENTHESIS: case OPEN_PARENTHESIS:
groupParen++; groupParen++;
break; break;
@ -314,24 +323,28 @@ public class PathCompiler {
case COMMA: case COMMA:
// In this state we've reach the end of a function parameter and we can pass along the parameter string // In this state we've reach the end of a function parameter and we can pass along the parameter string
// to the parser // to the parser
if (null != type && (0 == groupBrace && 0 == groupBracket && ((0 == groupParen && CLOSE_PARENTHESIS == c) || 1 == groupParen))) { if ((0 == groupQuote && 0 == groupBrace && 0 == groupBracket && ((0 == groupParen && CLOSE_PARENTHESIS == c) || 1 == groupParen))) {
Parameter param = new Parameter(); endOfStream = (0 == groupParen);
param.setType(type);
if (null != type) {
Parameter param = null;
if (type == ParamType.JSON) { if (type == ParamType.JSON) {
// parse the json and set the value // parse the json and set the value
param.setCachedValue(parameter.toString()); param = new Parameter(parameter.toString());
param.setEvaluated(true); } else if (type == ParamType.PATH) {
}
else if (type == ParamType.PATH) {
LinkedList<Predicate> predicates = new LinkedList<Predicate>(); LinkedList<Predicate> predicates = new LinkedList<Predicate>();
PathCompiler compiler = new PathCompiler(parameter.toString(), predicates); PathCompiler compiler = new PathCompiler(parameter.toString(), predicates);
param.setPath(compiler.compile()); param = new Parameter(compiler.compile());
} }
if (null != param) {
parameters.add(param); parameters.add(param);
} else {
// TODO: raise error...
}
parameter.delete(0, parameter.length()); parameter.delete(0, parameter.length());
type = null; type = null;
endOfStream = (0 == groupParen); }
} }
break; break;
} }
@ -339,6 +352,7 @@ public class PathCompiler {
if (type != null && !(c == COMMA && 0 == groupBrace && 0 == groupBracket && 1 == groupParen)) { if (type != null && !(c == COMMA && 0 == groupBrace && 0 == groupBracket && 1 == groupParen)) {
parameter.append(c); parameter.append(c);
} }
priorChar = c;
} }
path.setPosition(readPosition); path.setPosition(readPosition);
return parameters; return parameters;

5
json-path/src/test/java/com/jayway/jsonpath/internal/function/NestedFunctionTest.java

@ -49,4 +49,9 @@ public class NestedFunctionTest extends BaseFunctionTest {
public void testArrayAverageFunctionCallWithParameters() { public void testArrayAverageFunctionCallWithParameters() {
verifyMathFunction(conf, "$.numbers.sum($.numbers.min(), $.numbers.max())", 66.0); verifyMathFunction(conf, "$.numbers.sum($.numbers.min(), $.numbers.max())", 66.0);
} }
@Test
public void testJsonInnerArgumentArray() {
verifyMathFunction(conf, "$.sum(5, 3, $.numbers.max(), 2)", 20.0);
}
} }

Loading…
Cancel
Save