Browse Source

Fix #857 DCollecting all values for given key in object array returns empty Collection

pull/859/head
skwqy 2 years ago
parent
commit
bbd2bda832
  1. 48
      json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java

48
json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java

@ -32,7 +32,7 @@ public abstract class PathToken {
private int upstreamArrayIndex = -1; private int upstreamArrayIndex = -1;
public void setUpstreamArrayIndex(int idx) { public void setUpstreamArrayIndex(int idx){
upstreamArrayIndex = idx; upstreamArrayIndex = idx;
} }
@ -44,32 +44,32 @@ public abstract class PathToken {
void handleObjectProperty(String currentPath, Object model, EvaluationContextImpl ctx, List<String> properties) { void handleObjectProperty(String currentPath, Object model, EvaluationContextImpl ctx, List<String> properties) {
if (properties.size() == 1) { if(properties.size() == 1) {
String property = properties.get(0); String property = properties.get(0);
String evalPath = Utils.concat(currentPath, "['", property, "']"); String evalPath = Utils.concat(currentPath, "['", property, "']");
Object propertyVal = readObjectProperty(property, model, ctx); Object propertyVal = readObjectProperty(property, model, ctx);
if (propertyVal == JsonProvider.UNDEFINED) { if(propertyVal == JsonProvider.UNDEFINED){
// Conditions below heavily depend on current token type (and its logic) and are not "universal", // Conditions below heavily depend on current token type (and its logic) and are not "universal",
// so this code is quite dangerous (I'd rather rewrite it & move to PropertyPathToken and implemented // so this code is quite dangerous (I'd rather rewrite it & move to PropertyPathToken and implemented
// WildcardPathToken as a dynamic multi prop case of PropertyPathToken). // WildcardPathToken as a dynamic multi prop case of PropertyPathToken).
// Better safe than sorry. // Better safe than sorry.
assert this instanceof PropertyPathToken : "only PropertyPathToken is supported"; assert this instanceof PropertyPathToken : "only PropertyPathToken is supported";
if (isLeaf()) { if(isLeaf()) {
if (ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)) { if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){
propertyVal = null; propertyVal = null;
} else { } else {
if (ctx.options().contains(Option.SUPPRESS_EXCEPTIONS) || if(ctx.options().contains(Option.SUPPRESS_EXCEPTIONS) ||
!ctx.options().contains(Option.REQUIRE_PROPERTIES)) { !ctx.options().contains(Option.REQUIRE_PROPERTIES)){
return; return;
} else { } else {
throw new PathNotFoundException("No results for path: " + evalPath); throw new PathNotFoundException("No results for path: " + evalPath);
} }
} }
} else { } else {
if (!(isUpstreamDefinite() && isTokenDefinite()) && if (! (isUpstreamDefinite() && isTokenDefinite()) &&
!ctx.options().contains(Option.REQUIRE_PROPERTIES) || !ctx.options().contains(Option.REQUIRE_PROPERTIES) ||
ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)) { ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)){
// If there is some indefiniteness in the path and properties are not required - we'll ignore // If there is some indefiniteness in the path and properties are not required - we'll ignore
// absent property. And also in case of exception suppression - so that other path evaluation // absent property. And also in case of exception suppression - so that other path evaluation
// branches could be examined. // branches could be examined.
@ -82,11 +82,12 @@ public abstract class PathToken {
PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, property) : PathRef.NO_OP; PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, property) : PathRef.NO_OP;
if (isLeaf()) { if (isLeaf()) {
String idx = "[" + String.valueOf(upstreamArrayIndex) + "]"; String idx = "[" + String.valueOf(upstreamArrayIndex) + "]";
if (idx.equals("[-1]") || ctx.getRoot().getTail().prev().getPathFragment().equals(idx) || if(idx.equals("[-1]") || ctx.getRoot().getTail().prev().getPathFragment().equals(idx) ||
ctx.getRoot().getTail().prev().getPathFragment().equals("[*]")) { ctx.getRoot().getTail().prev().getPathFragment().equals("[*]")){
ctx.addResult(evalPath, pathRef, propertyVal); ctx.addResult(evalPath, pathRef, propertyVal);
} }
} else { }
else {
next().evaluate(evalPath, pathRef, propertyVal, ctx); next().evaluate(evalPath, pathRef, propertyVal, ctx);
} }
} else { } else {
@ -97,17 +98,17 @@ public abstract class PathToken {
Object merged = ctx.jsonProvider().createMap(); Object merged = ctx.jsonProvider().createMap();
for (String property : properties) { for (String property : properties) {
Object propertyVal; Object propertyVal;
if (hasProperty(property, model, ctx)) { if(hasProperty(property, model, ctx)) {
propertyVal = readObjectProperty(property, model, ctx); propertyVal = readObjectProperty(property, model, ctx);
if (propertyVal == JsonProvider.UNDEFINED) { if(propertyVal == JsonProvider.UNDEFINED){
if (ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)) { if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)) {
propertyVal = null; propertyVal = null;
} else { } else {
continue; continue;
} }
} }
} else { } else {
if (ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)) { if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){
propertyVal = null; propertyVal = null;
} else if (ctx.options().contains(Option.REQUIRE_PROPERTIES)) { } else if (ctx.options().contains(Option.REQUIRE_PROPERTIES)) {
throw new PathNotFoundException("Missing property in path " + evalPath); throw new PathNotFoundException("Missing property in path " + evalPath);
@ -146,7 +147,7 @@ public abstract class PathToken {
} }
} }
PathToken prev() { PathToken prev(){
return prev; return prev;
} }
@ -162,7 +163,7 @@ public abstract class PathToken {
} }
boolean isRoot() { boolean isRoot() {
return prev == null; return prev == null;
} }
boolean isUpstreamDefinite() { boolean isUpstreamDefinite() {
@ -176,7 +177,7 @@ public abstract class PathToken {
int cnt = 1; int cnt = 1;
PathToken token = this; PathToken token = this;
while (!token.isLeaf()) { while (!token.isLeaf()){
token = token.next(); token = token.next();
cnt++; cnt++;
} }
@ -184,7 +185,7 @@ public abstract class PathToken {
} }
public boolean isPathDefinite() { public boolean isPathDefinite() {
if (definite != null) { if(definite != null){
return definite.booleanValue(); return definite.booleanValue();
} }
boolean isDefinite = isTokenDefinite(); boolean isDefinite = isTokenDefinite();
@ -214,12 +215,11 @@ public abstract class PathToken {
return super.equals(obj); return super.equals(obj);
} }
public void invoke(PathFunction pathFunction, String currentPath, PathRef parent, Object model, public void invoke(PathFunction pathFunction, String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx) {
EvaluationContextImpl ctx) {
ctx.addResult(currentPath, parent, pathFunction.invoke(currentPath, parent, model, ctx, null)); ctx.addResult(currentPath, parent, pathFunction.invoke(currentPath, parent, model, ctx, null));
} }
public abstract void evaluate(String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx); public abstract void evaluate(String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx);
public abstract boolean isTokenDefinite(); public abstract boolean isTokenDefinite();

Loading…
Cancel
Save