All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jayway.jsonpath.Criteria Maven / Gradle / Ivy

There is a newer version: 2.9.0
Show newest version
/*
 * Copyright 2011 the original author or authors.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jayway.jsonpath;

import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.internal.filter.RelationalExpressionNode;
import com.jayway.jsonpath.internal.filter.RelationalOperator;
import com.jayway.jsonpath.internal.filter.ValueNode;
import com.jayway.jsonpath.internal.filter.ValueNodes;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

import static com.jayway.jsonpath.internal.Utils.notNull;
import static com.jayway.jsonpath.internal.filter.ValueNodes.PredicateNode;
import static com.jayway.jsonpath.internal.filter.ValueNodes.ValueListNode;

/**
 *
 */
@SuppressWarnings("unchecked")
public class Criteria implements Predicate {

    private final List criteriaChain;
    private ValueNode left;
    private RelationalOperator criteriaType;
    private ValueNode right;

    private Criteria(List criteriaChain, ValueNode left) {
        this.left = left;
        this.criteriaChain = criteriaChain;
        this.criteriaChain.add(this);
    }

    private Criteria(ValueNode left) {
        this(new LinkedList(), left);
    }

    @Override
    public boolean apply(PredicateContext ctx) {
        for (RelationalExpressionNode expressionNode : toRelationalExpressionNodes()) {
            if(!expressionNode.apply(ctx)){
                return false;
            }
        }
        return true;
    }

    @Override
    public String toString() {
        return Utils.join(" && ", toRelationalExpressionNodes());
    }

    private Collection toRelationalExpressionNodes(){
        List nodes = new ArrayList(criteriaChain.size());
        for (Criteria criteria : criteriaChain) {
            nodes.add(new RelationalExpressionNode(criteria.left, criteria.criteriaType, criteria.right));
        }
        return nodes;
    }

    /**
     * Static factory method to create a Criteria using the provided key
     *
     * @param key filed name
     * @return the new criteria
     */
    @Deprecated
    //This should be private.It exposes internal classes
    public static Criteria where(Path key) {
        return new Criteria(ValueNode.createPathNode(key));
    }


    /**
     * Static factory method to create a Criteria using the provided key
     *
     * @param key filed name
     * @return the new criteria
     */

    public static Criteria where(String key) {
        return new Criteria(ValueNode.toValueNode(prefixPath(key)));
    }

    /**
     * Static factory method to create a Criteria using the provided key
     *
     * @param key ads new filed to criteria
     * @return the criteria builder
     */
    public Criteria and(String key) {
        checkComplete();
        return new Criteria(this.criteriaChain, ValueNode.toValueNode(prefixPath(key)));
    }

    /**
     * Creates a criterion using equality
     *
     * @param o
     * @return the criteria
     */
    public Criteria is(Object o) {
        this.criteriaType = RelationalOperator.EQ;
        this.right = ValueNode.toValueNode(o);
        return this;
    }

    /**
     * Creates a criterion using equality
     *
     * @param o
     * @return the criteria
     */
    public Criteria eq(Object o) {
        return is(o);
    }

    /**
     * Creates a criterion using the != operator
     *
     * @param o
     * @return the criteria
     */
    public Criteria ne(Object o) {
        this.criteriaType = RelationalOperator.NE;
        this.right = ValueNode.toValueNode(o);
        return this;
    }

    /**
     * Creates a criterion using the < operator
     *
     * @param o
     * @return the criteria
     */
    public Criteria lt(Object o) {
        this.criteriaType = RelationalOperator.LT;
        this.right = ValueNode.toValueNode(o);
        return this;
    }

    /**
     * Creates a criterion using the <= operator
     *
     * @param o
     * @return the criteria
     */
    public Criteria lte(Object o) {
        this.criteriaType = RelationalOperator.LTE;
        this.right = ValueNode.toValueNode(o);
        return this;
    }

    /**
     * Creates a criterion using the > operator
     *
     * @param o
     * @return the criteria
     */
    public Criteria gt(Object o) {
        this.criteriaType = RelationalOperator.GT;
        this.right = ValueNode.toValueNode(o);
        return this;
    }

    /**
     * Creates a criterion using the >= operator
     *
     * @param o
     * @return the criteria
     */
    public Criteria gte(Object o) {
        this.criteriaType = RelationalOperator.GTE;
        this.right = ValueNode.toValueNode(o);
        return this;
    }

    /**
     * Creates a criterion using a Regex
     *
     * @param pattern
     * @return the criteria
     */
    public Criteria regex(Pattern pattern) {
        notNull(pattern, "pattern can not be null");
        this.criteriaType = RelationalOperator.REGEX;
        this.right = ValueNode.toValueNode(pattern);
        return this;
    }

    /**
     * The in operator is analogous to the SQL IN modifier, allowing you
     * to specify an array of possible matches.
     *
     * @param o the values to match against
     * @return the criteria
     */
    public Criteria in(Object... o) {
        return in(Arrays.asList(o));
    }

    /**
     * The in operator is analogous to the SQL IN modifier, allowing you
     * to specify an array of possible matches.
     *
     * @param c the collection containing the values to match against
     * @return the criteria
     */
    public Criteria in(Collection c) {
        notNull(c, "collection can not be null");
        this.criteriaType = RelationalOperator.IN;
        this.right = new ValueListNode(c);
        return this;
    }

    /**
     * The contains operator asserts that the provided object is contained
     * in the result. The object that should contain the input can be either an object or a String.
     *
     * @param o that should exists in given collection or
     * @return the criteria
     */
    public Criteria contains(Object o) {
        this.criteriaType = RelationalOperator.CONTAINS;
        this.right = ValueNode.toValueNode(o);
        return this;
    }

    /**
     * The nin operator is similar to $in except that it selects objects for
     * which the specified field does not have any value in the specified array.
     *
     * @param o the values to match against
     * @return the criteria
     */
    public Criteria nin(Object... o) {
        return nin(Arrays.asList(o));
    }

    /**
     * The nin operator is similar to $in except that it selects objects for
     * which the specified field does not have any value in the specified array.
     *
     * @param c the values to match against
     * @return the criteria
     */
    public Criteria nin(Collection c) {
        notNull(c, "collection can not be null");
        this.criteriaType = RelationalOperator.NIN;
        this.right = new ValueListNode(c);
        return this;
    }

    /**
     * The subsetof operator selects objects for which the specified field is
     * an array whose elements comprise a subset of the set comprised by the elements of
     * the specified array.
     *
     * @param o the values to match against
     * @return the criteria
     */
    public Criteria subsetof(Object... o) {
        return subsetof(Arrays.asList(o));
    }

    /**
     * The subsetof operator selects objects for which the specified field is
     * an array whose elements comprise a subset of the set comprised by the elements of
     * the specified array.
     *
     * @param c the values to match against
     * @return the criteria
     */
    public Criteria subsetof(Collection c) {
        notNull(c, "collection can not be null");
        this.criteriaType = RelationalOperator.SUBSETOF;
        this.right = new ValueListNode(c);
        return this;
    }

    /**
     * The anyof operator selects objects for which the specified field is
     * an array that contain at least an element in the specified array.
     *
     * @param o the values to match against
     * @return the criteria
     */
    public Criteria anyof(Object... o) {
        return subsetof(Arrays.asList(o));
    }

    /**
     * The anyof operator selects objects for which the specified field is
     * an array that contain at least an element in the specified array.
     *
     * @param c the values to match against
     * @return the criteria
     */
    public Criteria anyof(Collection c) {
        notNull(c, "collection can not be null");
        this.criteriaType = RelationalOperator.ANYOF;
        this.right = new ValueListNode(c);
        return this;
    }

    /**
     * The noneof operator selects objects for which the specified field is
     * an array that does not contain any of the elements of the specified array.
     *
     * @param o the values to match against
     * @return the criteria
     */
    public Criteria noneof(Object... o) {
        return noneof(Arrays.asList(o));
    }

    /**
     * The noneof operator selects objects for which the specified field is
     * an array that does not contain any of the elements of the specified array.
     *
     * @param c the values to match against
     * @return the criteria
     */
    public Criteria noneof(Collection c) {
        notNull(c, "collection can not be null");
        this.criteriaType = RelationalOperator.NONEOF;
        this.right = new ValueListNode(c);
        return this;
    }

    /**
     * The all operator is similar to $in, but instead of matching any value
     * in the specified array all values in the array must be matched.
     *
     * @param o
     * @return the criteria
     */
    public Criteria all(Object... o) {
        return all(Arrays.asList(o));
    }

    /**
     * The all operator is similar to $in, but instead of matching any value
     * in the specified array all values in the array must be matched.
     *
     * @param c
     * @return the criteria
     */
    public Criteria all(Collection c) {
        notNull(c, "collection can not be null");
        this.criteriaType = RelationalOperator.ALL;
        this.right = new ValueListNode(c);
        return this;
    }

    /**
     * The size operator matches:
     * 

*

    *
  1. array with the specified number of elements.
  2. *
  3. string with given length.
  4. *
* * @param size * @return the criteria */ public Criteria size(int size) { this.criteriaType = RelationalOperator.SIZE; this.right = ValueNode.toValueNode(size); return this; } /** * The $type operator matches values based on their Java JSON type. * * Supported types are: * * List.class * Map.class * String.class * Number.class * Boolean.class * * Other types evaluates to false * * @param clazz * @return the criteria */ public Criteria type(Class clazz) { this.criteriaType = RelationalOperator.TYPE; this.right = ValueNode.createClassNode(clazz); return this; } /** * Check for existence (or lack thereof) of a field. * * @param shouldExist * @return the criteria */ public Criteria exists(boolean shouldExist) { this.criteriaType = RelationalOperator.EXISTS; this.right = ValueNode.toValueNode(shouldExist); this.left = left.asPathNode().asExistsCheck(shouldExist); return this; } /** * The notEmpty operator checks that an array or String is not empty. * * @return the criteria */ @Deprecated public Criteria notEmpty() { return empty(false); } /** * The notEmpty operator checks that an array or String is empty. * * @param empty should be empty * @return the criteria */ public Criteria empty(boolean empty) { this.criteriaType = RelationalOperator.EMPTY; this.right = empty ? ValueNodes.TRUE : ValueNodes.FALSE; return this; } /** * The matches operator checks that an object matches the given predicate. * * @param p * @return the criteria */ public Criteria matches(Predicate p) { this.criteriaType = RelationalOperator.MATCHES; this.right = new PredicateNode(p); return this; } /** * Parse the provided criteria * * Deprecated use {@link Filter#parse(String)} * * @param criteria * @return a criteria */ @Deprecated public static Criteria parse(String criteria) { if(criteria == null){ throw new InvalidPathException("Criteria can not be null"); } String[] split = criteria.trim().split(" "); if(split.length == 3){ return create(split[0], split[1], split[2]); } else if(split.length == 1){ return create(split[0], "EXISTS", "true"); } else { throw new InvalidPathException("Could not parse criteria"); } } /** * Creates a new criteria * @param left path to evaluate in criteria * @param operator operator * @param right expected value * @return a new Criteria */ @Deprecated public static Criteria create(String left, String operator, String right) { Criteria criteria = new Criteria(ValueNode.toValueNode(left)); criteria.criteriaType = RelationalOperator.fromString(operator); criteria.right = ValueNode.toValueNode(right); return criteria; } private static String prefixPath(String key){ if (!key.startsWith("$") && !key.startsWith("@")) { key = "@." + key; } return key; } private void checkComplete(){ boolean complete = (left != null && criteriaType != null && right != null); if(!complete){ throw new JsonPathException("Criteria build exception. Complete on criteria before defining next."); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy