Browse Source

ArrayEvalFilter: add support for Javascript-style regular expressions.

pull/39/head
Laurent Charrière 11 years ago
parent
commit
f3e682f587
  1. 37
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java
  2. 10
      json-path/src/test/java/com/jayway/jsonpath/ComplianceTest.java

37
json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java

@ -33,6 +33,7 @@ public class ArrayEvalFilter extends PathTokenFilter {
private static final Pattern CONDITION_PATTERN = Pattern.compile("\\s?(@.*?)\\s?([!=<>]+)\\s?(.*?)\\s?");
private static final Pattern FIELD_EXISTS_PATTERN = Pattern.compile("\\s?@\\s?(.*?)\\s?");
private static final Pattern HASPATH_PATTERN = Pattern.compile("\\s?(@\\..*)\\s?(.*?)\\s?");
private static final Pattern REGEX_PATTERN = Pattern.compile("\\s?\\/(.*)\\/\\.test\\((@\\..*)\\)\\s?");
private Expression[] expressions;
@ -108,6 +109,12 @@ public class ArrayEvalFilter extends PathTokenFilter {
// evaluates @ or @.foo in expressions
return new HasPathExpression(condition);
}
Matcher regexMatcher = REGEX_PATTERN.matcher(condition);
if (regexMatcher.matches()) {
String regex = regexMatcher.group(1).trim();
String field = regexMatcher.group(2).trim();
return new RegexExpression(regex, field);
}
Matcher fieldExistsMatcher = FIELD_EXISTS_PATTERN.matcher(condition);
if (fieldExistsMatcher.matches()) {
// Field exists check, the single '@' in: $.menu.items[?(@ && @.id == 'ViewSVG')].id
@ -239,4 +246,34 @@ public class ArrayEvalFilter extends PathTokenFilter {
return false;
}
}
static class RegexExpression extends Expression {
private Pattern pattern;
private JsonPath path;
public RegexExpression(String regex, String field) {
pattern = Pattern.compile(regex);
if(field.startsWith("@.")){
this.path = JsonPath.compile(field.replace("@.", "$."));
} else {
this.path = JsonPath.compile(field.replace("@", "$"));
}
}
@Override
public boolean evaluate(Object obj, Configuration configuration) {
JsonProvider jsonProvider = configuration.getProvider();
if(jsonProvider.isMap(obj)){
try{
Object value = (obj != null) ? path.read(obj, configuration.options(Option.THROW_ON_MISSING_PROPERTY)) : null;
return (value instanceof String) && pattern.matcher((String)value).find();
} catch (PathNotFoundException e){
return false;
}
}
return false;
}
}
}

10
json-path/src/test/java/com/jayway/jsonpath/ComplianceTest.java

@ -118,7 +118,7 @@ public class ComplianceTest {
assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.id == 'ViewSVG')].id"), hasItems("ViewSVG"));
//assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.id && !@.label)].id"), hasItems("?")); //low
//assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.label && /SVG/.test(@.label))].id"), hasItems("?")); //low
assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.label && /SVG/.test(@.label))].id"), hasItems("CopySVG", "ViewSVG")); //low
//assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(!@)]"), hasItems("?")); //low
//assertThat(JsonPath.<List<String>>read(json, "$..[0]"), hasItems("?")); //low
@ -145,7 +145,7 @@ public class ComplianceTest {
"p": [ "$[0]",
"$[4]",
"$[*]",
"$[-1:]"
"$[-1:]"
]
},
--three
@ -199,7 +199,7 @@ public class ComplianceTest {
"p": [ "$.menu.items[?(@ && @.id && !@.label)].id",
"$.menu.items[?(@ && @.label && /SVG/.test(@.label))].id",
"$.menu.items[?(!@)]",
"$..[0]"
"$..[0]"
]
},
--five
@ -207,8 +207,8 @@ public class ComplianceTest {
b: [5,6,7,8]
},
"p": [ "$..[0]",
"$..[-1:]",
"$..[?(@%2==0)]"
"$..[-1:]",
"$..[?(@%2==0)]"
]
},
{ "o": { lin: {color:"red", x:2, y:3},

Loading…
Cancel
Save