From 2dae575f35b8f8663f6f20d7387b91e6717d3320 Mon Sep 17 00:00:00 2001 From: Kalle Stenflo Date: Sun, 15 Nov 2015 14:18:25 +0100 Subject: [PATCH] Moved PathNode into ValueNode. --- .../java/com/jayway/jsonpath/Criteria.java | 3 +- .../internal/filter/EvaluatorFactory.java | 2 +- .../internal/filter/FilterCompiler.java | 6 +- .../internal/filter/FunctionNode.java | 11 -- .../jsonpath/internal/filter/PathNode.java | 111 ------------------ .../jsonpath/internal/filter/ValueNode.java | 109 +++++++++++++++++ 6 files changed, 114 insertions(+), 128 deletions(-) delete mode 100644 json-path/src/main/java/com/jayway/jsonpath/internal/filter/FunctionNode.java delete mode 100644 json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathNode.java diff --git a/json-path/src/main/java/com/jayway/jsonpath/Criteria.java b/json-path/src/main/java/com/jayway/jsonpath/Criteria.java index 0a665b57..fec99bf2 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/Criteria.java +++ b/json-path/src/main/java/com/jayway/jsonpath/Criteria.java @@ -16,7 +16,6 @@ package com.jayway.jsonpath; import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.Utils; -import com.jayway.jsonpath.internal.filter.PathNode; import com.jayway.jsonpath.internal.filter.RelationalExpressionNode; import com.jayway.jsonpath.internal.filter.RelationalOperator; import com.jayway.jsonpath.internal.filter.ValueNode; @@ -84,7 +83,7 @@ public class Criteria implements Predicate { @Deprecated //This should be private.It exposes internal classes public static Criteria where(Path key) { - return new Criteria(new PathNode(key)); + return new Criteria(ValueNode.createPathNode(key)); } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java index 8b9a72ef..d8632fa1 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java @@ -46,7 +46,7 @@ public class EvaluatorFactory { private static class NotEqualsEvaluator implements Evaluator { @Override public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { - return !left.equals(right); + return !evaluators.get(RelationalOperator.EQ).evaluate(left, right, ctx); } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java index 4dd670a2..cb4dd835 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java @@ -148,7 +148,7 @@ public class FilterCompiler { private RelationalExpressionNode readExpression() { ValueNode left = readValueNode(); if(expressionIsTerminated()) { - PathNode pathNode = left.asPathNode(); + ValueNode.PathNode pathNode = left.asPathNode(); left = pathNode.asExistsCheck(pathNode.shouldExists()); RelationalOperator operator = RelationalOperator.EXISTS; ValueNode right = left.asPathNode().shouldExists() ? ValueNode.TRUE : ValueNode.FALSE; @@ -287,7 +287,7 @@ public class FilterCompiler { return ValueNode.createBooleanNode(boolValue); } - private PathNode readPath() { + private ValueNode.PathNode readPath() { char previousSignificantChar = filter.previousSignificantChar(); int begin = filter.position(); @@ -313,7 +313,7 @@ public class FilterCompiler { boolean shouldExists = !(previousSignificantChar == BANG); CharSequence path = filter.subSequence(begin, filter.position()); - return new PathNode(path, false, shouldExists); + return ValueNode.createPathNode(path, false, shouldExists); } private boolean expressionIsTerminated(){ diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FunctionNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FunctionNode.java deleted file mode 100644 index da07853e..00000000 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FunctionNode.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.jayway.jsonpath.internal.filter; - -import com.jayway.jsonpath.Predicate; - -public class FunctionNode extends ValueNode { - - @Override - public Class type(Predicate.PredicateContext ctx) { - return Void.class; - } -} diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathNode.java deleted file mode 100644 index 4005fe3f..00000000 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathNode.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.jayway.jsonpath.internal.filter; - -import com.jayway.jsonpath.Configuration; -import com.jayway.jsonpath.JsonPathException; -import com.jayway.jsonpath.Option; -import com.jayway.jsonpath.PathNotFoundException; -import com.jayway.jsonpath.Predicate; -import com.jayway.jsonpath.internal.Path; -import com.jayway.jsonpath.internal.PathCompiler; -import com.jayway.jsonpath.internal.token.PredicateContextImpl; -import com.jayway.jsonpath.spi.json.JsonProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.math.BigDecimal; - -public class PathNode extends ValueNode { - - private static final Logger logger = LoggerFactory.getLogger(PathNode.class); - - private final Path path; - private final boolean existsCheck; - private final boolean shouldExist; - - public PathNode(Path path) { - this(path, false, false); - } - - public PathNode(CharSequence charSequence, boolean existsCheck, boolean shouldExist) { - this(PathCompiler.compile(charSequence.toString()), existsCheck, shouldExist); - } - - public PathNode(Path path, boolean existsCheck, boolean shouldExist) { - this.path = path; - this.existsCheck = existsCheck; - this.shouldExist = shouldExist; - logger.trace("PathNode {} existsCheck: {}", path, existsCheck); - } - - public Path getPath() { - return path; - } - - public boolean isExistsCheck() { - return existsCheck; - } - - public boolean shouldExists() { - return shouldExist; - } - - @Override - public Class type(Predicate.PredicateContext ctx) { - return Void.class; - } - - public boolean isPathNode() { - return true; - } - - public PathNode asPathNode() { - return this; - } - - public PathNode asExistsCheck(boolean shouldExist) { - return new PathNode(path, true, shouldExist); - } - - @Override - public String toString() { - return path.toString(); - } - - public ValueNode evaluate(Predicate.PredicateContext ctx) { - Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).options(Option.REQUIRE_PROPERTIES).build(); - if (isExistsCheck()) { - try { - Object result = path.evaluate(ctx.item(), ctx.root(), c).getValue(false); - return result == JsonProvider.UNDEFINED ? ValueNode.FALSE : ValueNode.TRUE; - } catch (PathNotFoundException e) { - return ValueNode.FALSE; - } - } else { - try { - Object res; - if (ctx instanceof PredicateContextImpl) { - //This will use cache for document ($) queries - PredicateContextImpl ctxi = (PredicateContextImpl) ctx; - res = ctxi.evaluate(path); - } else { - Object doc = path.isRootPath() ? ctx.root() : ctx.item(); - res = path.evaluate(doc, ctx.root(), ctx.configuration()).getValue(); - } - res = ctx.configuration().jsonProvider().unwrap(res); - - if (res instanceof Number) return ValueNode.createNumberNode(res.toString()); - else if (res instanceof BigDecimal) return ValueNode.createNumberNode(res.toString()); - else if (res instanceof String) return ValueNode.createStringNode(res.toString(), false); - else if (res instanceof Boolean) return ValueNode.createBooleanNode(res.toString()); - else if (res == null) return ValueNode.NULL_NODE; - else if (ctx.configuration().jsonProvider().isArray(res)) return ValueNode.createJsonNode(res); - else if (ctx.configuration().jsonProvider().isMap(res)) return ValueNode.createJsonNode(res); - else throw new JsonPathException("Could not convert " + res.toString() + " to a ValueNode"); - } catch (PathNotFoundException e) { - return ValueNode.UNDEFINED; - } - } - } - - -} \ No newline at end of file diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java index cc1c19e5..0985dbfd 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java @@ -3,9 +3,16 @@ package com.jayway.jsonpath.internal.filter; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.InvalidPathException; import com.jayway.jsonpath.JsonPathException; +import com.jayway.jsonpath.Option; +import com.jayway.jsonpath.PathNotFoundException; import com.jayway.jsonpath.Predicate; +import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.PathCompiler; import com.jayway.jsonpath.internal.Utils; +import com.jayway.jsonpath.internal.token.PredicateContextImpl; +import com.jayway.jsonpath.spi.json.JsonProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.math.BigDecimal; import java.util.ArrayList; @@ -216,6 +223,14 @@ public abstract class ValueNode { return UNDEFINED; } + public static PathNode createPathNode(CharSequence path, boolean existsCheck, boolean shouldExists) { + return new PathNode(path, existsCheck, shouldExists); + } + + public static ValueNode createPathNode(Path path) { + return new PathNode(path); + } + //---------------------------------------------------- // // ValueNode Implementations @@ -702,5 +717,99 @@ public abstract class ValueNode { } } + public static class PathNode extends ValueNode { + + private static final Logger logger = LoggerFactory.getLogger(PathNode.class); + + private final Path path; + private final boolean existsCheck; + private final boolean shouldExist; + + PathNode(Path path) { + this(path, false, false); + } + + PathNode(CharSequence charSequence, boolean existsCheck, boolean shouldExist) { + this(PathCompiler.compile(charSequence.toString()), existsCheck, shouldExist); + } + + PathNode(Path path, boolean existsCheck, boolean shouldExist) { + this.path = path; + this.existsCheck = existsCheck; + this.shouldExist = shouldExist; + logger.trace("PathNode {} existsCheck: {}", path, existsCheck); + } + + public Path getPath() { + return path; + } + public boolean isExistsCheck() { + return existsCheck; + } + + public boolean shouldExists() { + return shouldExist; + } + + @Override + public Class type(Predicate.PredicateContext ctx) { + return Void.class; + } + + public boolean isPathNode() { + return true; + } + + public PathNode asPathNode() { + return this; + } + + public PathNode asExistsCheck(boolean shouldExist) { + return new PathNode(path, true, shouldExist); + } + + @Override + public String toString() { + return path.toString(); + } + + public ValueNode evaluate(Predicate.PredicateContext ctx) { + Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).options(Option.REQUIRE_PROPERTIES).build(); + if (isExistsCheck()) { + try { + Object result = path.evaluate(ctx.item(), ctx.root(), c).getValue(false); + return result == JsonProvider.UNDEFINED ? ValueNode.FALSE : ValueNode.TRUE; + } catch (PathNotFoundException e) { + return ValueNode.FALSE; + } + } else { + try { + Object res; + if (ctx instanceof PredicateContextImpl) { + //This will use cache for document ($) queries + PredicateContextImpl ctxi = (PredicateContextImpl) ctx; + res = ctxi.evaluate(path); + } else { + Object doc = path.isRootPath() ? ctx.root() : ctx.item(); + res = path.evaluate(doc, ctx.root(), ctx.configuration()).getValue(); + } + res = ctx.configuration().jsonProvider().unwrap(res); + + if (res instanceof Number) return ValueNode.createNumberNode(res.toString()); + else if (res instanceof BigDecimal) return ValueNode.createNumberNode(res.toString()); + else if (res instanceof String) return ValueNode.createStringNode(res.toString(), false); + else if (res instanceof Boolean) return ValueNode.createBooleanNode(res.toString()); + else if (res == null) return ValueNode.NULL_NODE; + else if (ctx.configuration().jsonProvider().isArray(res)) return ValueNode.createJsonNode(res); + else if (ctx.configuration().jsonProvider().isMap(res)) return ValueNode.createJsonNode(res); + else throw new JsonPathException("Could not convert " + res.toString() + " to a ValueNode"); + } catch (PathNotFoundException e) { + return ValueNode.UNDEFINED; + } + } + } + + + } } \ No newline at end of file