Browse Source

Moved PathNode into ValueNode.

pull/183/merge
Kalle Stenflo 9 years ago
parent
commit
2dae575f35
  1. 3
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  2. 2
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java
  3. 6
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java
  4. 11
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/FunctionNode.java
  5. 111
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathNode.java
  6. 109
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java

3
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));
}

2
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);
}
}

6
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(){

11
json-path/src/main/java/com/jayway/jsonpath/internal/filter/FunctionNode.java

@ -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;
}
}

111
json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathNode.java

@ -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;
}
}
}
}

109
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;
}
}
}
}
}
Loading…
Cancel
Save