use of com.jayway.jsonpath.Predicate in project JsonPath by jayway.
the class FilterTest method arrays_of_maps_can_be_filtered.
@Test
public void arrays_of_maps_can_be_filtered() throws Exception {
Map<String, Object> rootGrandChild_A = new HashMap<String, Object>();
rootGrandChild_A.put("name", "rootGrandChild_A");
Map<String, Object> rootGrandChild_B = new HashMap<String, Object>();
rootGrandChild_B.put("name", "rootGrandChild_B");
Map<String, Object> rootGrandChild_C = new HashMap<String, Object>();
rootGrandChild_C.put("name", "rootGrandChild_C");
Map<String, Object> rootChild_A = new HashMap<String, Object>();
rootChild_A.put("name", "rootChild_A");
rootChild_A.put("children", asList(rootGrandChild_A, rootGrandChild_B, rootGrandChild_C));
Map<String, Object> rootChild_B = new HashMap<String, Object>();
rootChild_B.put("name", "rootChild_B");
rootChild_B.put("children", asList(rootGrandChild_A, rootGrandChild_B, rootGrandChild_C));
Map<String, Object> rootChild_C = new HashMap<String, Object>();
rootChild_C.put("name", "rootChild_C");
rootChild_C.put("children", asList(rootGrandChild_A, rootGrandChild_B, rootGrandChild_C));
Map<String, Object> root = new HashMap<String, Object>();
root.put("children", asList(rootChild_A, rootChild_B, rootChild_C));
Predicate customFilter = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
if (ctx.configuration().jsonProvider().getMapValue(ctx.item(), "name").equals("rootGrandChild_A")) {
return true;
}
return false;
}
};
Filter rootChildFilter = filter(where("name").regex(Pattern.compile("rootChild_[A|B]")));
Filter rootGrandChildFilter = filter(where("name").regex(Pattern.compile("rootGrandChild_[A|B]")));
List read = JsonPath.read(root, "children[?].children[?, ?]", rootChildFilter, rootGrandChildFilter, customFilter);
}
use of com.jayway.jsonpath.Predicate in project JsonPath by jayway.
the class FilterTest method arrays_of_objects_can_be_filtered.
@Test
public void arrays_of_objects_can_be_filtered() throws Exception {
Map<String, Object> doc = new HashMap<String, Object>();
doc.put("items", asList(1, 2, 3));
Predicate customFilter = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
return 1 == (Integer) ctx.item();
}
};
List<Integer> res = JsonPath.read(doc, "$.items[?]", customFilter);
assertEquals(1, res.get(0).intValue());
}
use of com.jayway.jsonpath.Predicate in project JsonPath by jayway.
the class PathCompiler method parseFunctionParameters.
/**
* Parse the parameters of a function call, either the caller has supplied JSON data, or the caller has supplied
* another path expression which must be evaluated and in turn invoked against the root document. In this tokenizer
* we're only concerned with parsing the path thus the output of this function is a list of parameters with the Path
* set if the parameter is an expression. If the parameter is a JSON document then the value of the cachedValue is
* set on the object.
*
* Sequence for parsing out the parameters:
*
* This code has its own tokenizer - it does some rudimentary level of lexing in that it can distinguish between JSON block parameters
* and sub-JSON blocks - it effectively regex's out the parameters into string blocks that can then be passed along to the appropriate parser.
* Since sub-jsonpath expressions can themselves contain other function calls this routine needs to be sensitive to token counting to
* determine the boundaries. Since the Path parser isn't aware of JSON processing this uber routine is needed.
*
* Parameters are separated by COMMAs ','
*
* <pre>
* doc = {"numbers": [1,2,3,4,5,6,7,8,9,10]}
*
* $.sum({10}, $.numbers.avg())
* </pre>
*
* The above is a valid function call, we're first summing 10 + avg of 1...10 (5.5) so the total should be 15.5
*
* @return
* An ordered list of parameters that are to processed via the function. Typically functions either process
* an array of values and/or can consume parameters in addition to the values provided from the consumption of
* an array.
*/
private List<Parameter> parseFunctionParameters(String funcName) {
PathToken currentToken;
ParamType type = null;
// 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, groupQuote = 0;
Boolean endOfStream = false;
char priorChar = 0;
List<Parameter> parameters = new ArrayList<Parameter>();
StringBuffer parameter = new StringBuffer();
while (path.inBounds() && !endOfStream) {
char c = path.currentChar();
path.incrementPosition(1);
// we're at the start of the stream, and don't know what type of parameter we have
if (type == null) {
if (isWhitespace(c)) {
continue;
}
if (c == OPEN_BRACE || isDigit(c) || DOUBLE_QUOTE == c) {
type = ParamType.JSON;
} else if (isPathContext(c)) {
// read until we reach a terminating comma and we've reset grouping to zero
type = ParamType.PATH;
}
}
switch(c) {
case DOUBLE_QUOTE:
if (priorChar != '\\' && groupQuote > 0) {
if (groupQuote == 0) {
throw new InvalidPathException("Unexpected quote '\"' at character position: " + path.position());
}
groupQuote--;
} else {
groupQuote++;
}
break;
case OPEN_PARENTHESIS:
groupParen++;
break;
case OPEN_BRACE:
groupBrace++;
break;
case OPEN_SQUARE_BRACKET:
groupBracket++;
break;
case CLOSE_BRACE:
if (0 == groupBrace) {
throw new InvalidPathException("Unexpected close brace '}' at character position: " + path.position());
}
groupBrace--;
break;
case CLOSE_SQUARE_BRACKET:
if (0 == groupBracket) {
throw new InvalidPathException("Unexpected close bracket ']' at character position: " + path.position());
}
groupBracket--;
break;
// we've encountered a COMMA do the same
case CLOSE_PARENTHESIS:
groupParen--;
if (0 != groupParen) {
parameter.append(c);
}
case COMMA:
// to the parser
if ((0 == groupQuote && 0 == groupBrace && 0 == groupBracket && ((0 == groupParen && CLOSE_PARENTHESIS == c) || 1 == groupParen))) {
endOfStream = (0 == groupParen);
if (null != type) {
Parameter param = null;
switch(type) {
case JSON:
// parse the json and set the value
param = new Parameter(parameter.toString());
break;
case PATH:
LinkedList<Predicate> predicates = new LinkedList<Predicate>();
PathCompiler compiler = new PathCompiler(parameter.toString(), predicates);
param = new Parameter(compiler.compile());
break;
}
if (null != param) {
parameters.add(param);
}
parameter.delete(0, parameter.length());
type = null;
}
}
break;
}
if (type != null && !(c == COMMA && 0 == groupBrace && 0 == groupBracket && 1 == groupParen)) {
parameter.append(c);
}
priorChar = c;
}
if (0 != groupBrace || 0 != groupParen || 0 != groupBracket) {
throw new InvalidPathException("Arguments to function: '" + funcName + "' are not closed properly.");
}
return parameters;
}
use of com.jayway.jsonpath.Predicate in project JsonPath by jayway.
the class PathCompiler method readFilterToken.
//
// [?(...)]
//
private boolean readFilterToken(PathTokenAppender appender) {
if (!path.currentCharIs(OPEN_SQUARE_BRACKET) && !path.nextSignificantCharIs(BEGIN_FILTER)) {
return false;
}
int openStatementBracketIndex = path.position();
int questionMarkIndex = path.indexOfNextSignificantChar(BEGIN_FILTER);
if (questionMarkIndex == -1) {
return false;
}
int openBracketIndex = path.indexOfNextSignificantChar(questionMarkIndex, OPEN_PARENTHESIS);
if (openBracketIndex == -1) {
return false;
}
int closeBracketIndex = path.indexOfClosingBracket(openBracketIndex, true, true);
if (closeBracketIndex == -1) {
return false;
}
if (!path.nextSignificantCharIs(closeBracketIndex, CLOSE_SQUARE_BRACKET)) {
return false;
}
int closeStatementBracketIndex = path.indexOfNextSignificantChar(closeBracketIndex, CLOSE_SQUARE_BRACKET);
String criteria = path.subSequence(openStatementBracketIndex, closeStatementBracketIndex + 1).toString();
Predicate predicate = FilterCompiler.compile(criteria);
appender.appendPathToken(PathTokenFactory.createPredicatePathToken(predicate));
path.setPosition(closeStatementBracketIndex + 1);
return path.currentIsTail() || readNextToken(appender);
}
Aggregations