diff --git a/json-path/src/main/java/com/jayway/jsonpath/Filter.java b/json-path/src/main/java/com/jayway/jsonpath/Filter.java index ab92b286..765fa0c1 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/Filter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/Filter.java @@ -14,27 +14,44 @@ */ package com.jayway.jsonpath; +import com.jayway.jsonpath.internal.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; import java.util.Stack; import java.util.regex.Pattern; +import static java.util.Arrays.asList; + /** * */ public abstract class Filter implements Predicate { + private static final Logger logger = LoggerFactory.getLogger(Filter.class); private static final Pattern OPERATOR_SPLIT = Pattern.compile("((?<=&&|\\|\\|)|(?=&&|\\|\\|))"); private static final String AND = "&&"; private static final String OR = "||"; /** * Creates a new Filter based on given criteria - * @param criteria criteria + * @param predicate criteria * @return a new Filter */ - public static Filter filter(Predicate criteria) { - return new SingleFilter(criteria); + public static Filter filter(Predicate predicate) { + return new SingleFilter(predicate); } + /** + * Create a new Filter based on given list of criteria. + * @param predicates list of criteria all needs to evaluate to true + * @return + */ + public static Filter filter(Collection predicates) { + return new AndFilter(predicates); + } @Override public abstract boolean apply(PredicateContext ctx); @@ -48,6 +65,8 @@ public abstract class Filter implements Predicate { return new AndFilter(this, other); } + + private static final class SingleFilter extends Filter { private final Predicate predicate; @@ -69,23 +88,35 @@ public abstract class Filter implements Predicate { private static final class AndFilter extends Filter { - private final Predicate left; - private final Predicate right; + Collection predicates; + + private AndFilter(Collection predicates) { + this.predicates = predicates; + } private AndFilter(Predicate left, Predicate right) { - this.left = left; - this.right = right; + this(asList(left, right)); + } + + public Filter and(final Predicate other){ + Collection newPredicates = new ArrayList(predicates); + newPredicates.add(other); + return new AndFilter(newPredicates); } @Override public boolean apply(PredicateContext ctx) { - boolean a = left.apply(ctx); - return a && right.apply(ctx); + for (Predicate predicate : predicates) { + if(!predicate.apply(ctx)){ + return false; + } + } + return true; } @Override public String toString() { - return left.toString() + " && " + right.toString(); + return "(" + Utils.join(" && ", predicates) + ")"; } } @@ -111,7 +142,7 @@ public abstract class Filter implements Predicate { @Override public String toString() { - return left.toString() + " || " + right.toString(); + return "(" + left.toString() + " || " + right.toString() + ")"; } } @@ -160,6 +191,8 @@ public abstract class Filter implements Predicate { if(!operators.isEmpty() || !criteria.isEmpty()){ throw new InvalidPathException("Invalid operators " + filter); } + + if(logger.isDebugEnabled()) logger.debug("Parsed filter: " + root.toString()); return root; }