/** * Creates a new criteria * * @param left path to evaluate in criteria * @param operator operator * @param right expected value * @return a new Criteria */ public static Criteria create(String left, String operator, String right) { Object leftPrepared = left; Object rightPrepared = right; Path leftPath = null; Path rightPath = null; if (isPath(left)) { leftPath = PathCompiler.compile(left); if (!leftPath.isDefinite()) { throw new InvalidPathException("the predicate path: " + left + " is not definite"); } leftPrepared = leftPath; } else if (isString(left)) { leftPrepared = left.substring(1, left.length() - 1); } if (isPath(right)) { rightPath = PathCompiler.compile(right); if (!rightPath.isDefinite()) { throw new InvalidPathException("the predicate path: " + right + " is not definite"); } rightPrepared = rightPath; } else if (isString(right)) { rightPrepared = right.substring(1, right.length() - 1); } if (leftPath != null && operator.isEmpty()) { return Criteria.where(leftPath).exists(true); } else { return new Criteria(leftPrepared, CriteriaType.parse(operator), rightPrepared); } }
private boolean eval(PredicateContext ctx) { if (CriteriaType.EXISTS == criteriaType) { boolean exists = ((Boolean) right); try { Configuration c = Configuration.builder() .jsonProvider(ctx.configuration().jsonProvider()) .options(Option.REQUIRE_PROPERTIES) .build(); ((Path) left).evaluate(ctx.item(), ctx.root(), c).getValue(); return exists; } catch (PathNotFoundException e) { return !exists; } } else { try { Object leftVal = evaluateIfPath(left, ctx); Object rightVal = evaluateIfPath(right, ctx); return criteriaType.eval(rightVal, leftVal, ctx); } catch (ValueCompareException e) { return false; } catch (PathNotFoundException e) { return false; } } }
private Object evaluateIfPath(Object target, PredicateContext ctx) { Object res = target; if (res instanceof Path) { Path leftPath = (Path) target; if (ctx instanceof PredicateContextImpl) { // This will use cache for document ($) queries PredicateContextImpl ctxi = (PredicateContextImpl) ctx; res = ctxi.evaluate(leftPath); } else { Object doc = leftPath.isRootPath() ? ctx.root() : ctx.item(); res = leftPath.evaluate(doc, ctx.root(), ctx.configuration()).getValue(); } } return res; }