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.Path;
import com.jayway.jsonpath.internal.Utils; 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.RelationalExpressionNode;
import com.jayway.jsonpath.internal.filter.RelationalOperator; import com.jayway.jsonpath.internal.filter.RelationalOperator;
import com.jayway.jsonpath.internal.filter.ValueNode; import com.jayway.jsonpath.internal.filter.ValueNode;
@ -84,7 +83,7 @@ public class Criteria implements Predicate {
@Deprecated @Deprecated
//This should be private.It exposes internal classes //This should be private.It exposes internal classes
public static Criteria where(Path key) { 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 { private static class NotEqualsEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { 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() { private RelationalExpressionNode readExpression() {
ValueNode left = readValueNode(); ValueNode left = readValueNode();
if(expressionIsTerminated()) { if(expressionIsTerminated()) {
PathNode pathNode = left.asPathNode(); ValueNode.PathNode pathNode = left.asPathNode();
left = pathNode.asExistsCheck(pathNode.shouldExists()); left = pathNode.asExistsCheck(pathNode.shouldExists());
RelationalOperator operator = RelationalOperator.EXISTS; RelationalOperator operator = RelationalOperator.EXISTS;
ValueNode right = left.asPathNode().shouldExists() ? ValueNode.TRUE : ValueNode.FALSE; ValueNode right = left.asPathNode().shouldExists() ? ValueNode.TRUE : ValueNode.FALSE;
@ -287,7 +287,7 @@ public class FilterCompiler {
return ValueNode.createBooleanNode(boolValue); return ValueNode.createBooleanNode(boolValue);
} }
private PathNode readPath() { private ValueNode.PathNode readPath() {
char previousSignificantChar = filter.previousSignificantChar(); char previousSignificantChar = filter.previousSignificantChar();
int begin = filter.position(); int begin = filter.position();
@ -313,7 +313,7 @@ public class FilterCompiler {
boolean shouldExists = !(previousSignificantChar == BANG); boolean shouldExists = !(previousSignificantChar == BANG);
CharSequence path = filter.subSequence(begin, filter.position()); CharSequence path = filter.subSequence(begin, filter.position());
return new PathNode(path, false, shouldExists); return ValueNode.createPathNode(path, false, shouldExists);
} }
private boolean expressionIsTerminated(){ 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.Configuration;
import com.jayway.jsonpath.InvalidPathException; import com.jayway.jsonpath.InvalidPathException;
import com.jayway.jsonpath.JsonPathException; import com.jayway.jsonpath.JsonPathException;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.PathNotFoundException;
import com.jayway.jsonpath.Predicate; import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.PathCompiler; import com.jayway.jsonpath.internal.PathCompiler;
import com.jayway.jsonpath.internal.Utils; 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.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
@ -216,6 +223,14 @@ public abstract class ValueNode {
return UNDEFINED; 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 // 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