|
|
|
@ -4,6 +4,8 @@ import java.util.Collection;
|
|
|
|
|
import java.util.LinkedHashMap; |
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
import com.jayway.jsonpath.spi.json.JsonProvider; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
@ -39,7 +41,7 @@ public class ScanPathToken extends PathToken {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void walk(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { |
|
|
|
|
public static void walk(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { |
|
|
|
|
if (ctx.jsonProvider().isMap(model)) { |
|
|
|
|
walkObject(currentPath, model, ctx, predicate, predicateMatches); |
|
|
|
|
} else if (ctx.jsonProvider().isArray(model)) { |
|
|
|
@ -47,7 +49,7 @@ public class ScanPathToken extends PathToken {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void walkArray(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { |
|
|
|
|
public static void walkArray(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { |
|
|
|
|
|
|
|
|
|
if (predicate.matches(model)) { |
|
|
|
|
predicateMatches.put(currentPath, model); |
|
|
|
@ -69,7 +71,7 @@ public class ScanPathToken extends PathToken {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void walkObject(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { |
|
|
|
|
public static void walkObject(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { |
|
|
|
|
|
|
|
|
|
if (predicate.matches(model)) { |
|
|
|
|
predicateMatches.put(currentPath, model); |
|
|
|
@ -79,96 +81,124 @@ public class ScanPathToken extends PathToken {
|
|
|
|
|
for (String property : properties) { |
|
|
|
|
String evalPath = currentPath + "['" + property + "']"; |
|
|
|
|
Object propertyModel = ctx.jsonProvider().getMapValue(model, property); |
|
|
|
|
if (propertyModel != JsonProvider.UNDEFINED) { |
|
|
|
|
walk(evalPath, propertyModel, ctx, predicate, predicateMatches); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private Predicate createScanPredicate(final PathToken target, final EvaluationContextImpl ctx) { |
|
|
|
|
private static Predicate createScanPredicate(final PathToken target, final EvaluationContextImpl ctx) { |
|
|
|
|
if (target instanceof PropertyPathToken) { |
|
|
|
|
return new Predicate() { |
|
|
|
|
private PropertyPathToken propertyPathToken = (PropertyPathToken) target; |
|
|
|
|
return new PropertyPathTokenPredicate(target, ctx); |
|
|
|
|
} else if (target instanceof ArrayPathToken) { |
|
|
|
|
return new ArrayPathTokenPredicate(ctx); |
|
|
|
|
} else if (target instanceof WildcardPathToken) { |
|
|
|
|
return new WildcardPathTokenPredicate(); |
|
|
|
|
} else if (target instanceof FilterPathToken) { |
|
|
|
|
return new FilterPathTokenPredicate(target, ctx); |
|
|
|
|
} else { |
|
|
|
|
return FALSE_PREDICATE; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Class<?> clazz() { |
|
|
|
|
return PropertyPathToken.class; |
|
|
|
|
boolean isTokenDefinite() { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public boolean matches(Object model) { |
|
|
|
|
Collection<String> keys = ctx.jsonProvider().getPropertyKeys(model); |
|
|
|
|
return keys.containsAll(propertyPathToken.getProperties()); |
|
|
|
|
public String getPathFragment() { |
|
|
|
|
return ".."; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} else if (target instanceof ArrayPathToken) { |
|
|
|
|
return new Predicate() { |
|
|
|
|
|
|
|
|
|
private static interface Predicate { |
|
|
|
|
Class<?> clazz(); |
|
|
|
|
|
|
|
|
|
boolean matches(Object model); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static final Predicate FALSE_PREDICATE = new Predicate() { |
|
|
|
|
@Override |
|
|
|
|
public Class<?> clazz() { |
|
|
|
|
return ArrayPathToken.class; |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public boolean matches(Object model) { |
|
|
|
|
return ctx.jsonProvider().isArray(model); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} else if (target instanceof WildcardPathToken) { |
|
|
|
|
return new Predicate() { |
|
|
|
|
|
|
|
|
|
private static final class FilterPathTokenPredicate implements Predicate { |
|
|
|
|
private final EvaluationContextImpl ctx; |
|
|
|
|
private FilterPathToken filterPathToken; |
|
|
|
|
|
|
|
|
|
private FilterPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { |
|
|
|
|
this.ctx = ctx; |
|
|
|
|
filterPathToken = (FilterPathToken) target; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Class<?> clazz() { |
|
|
|
|
return WildcardPathToken.class; |
|
|
|
|
return FilterPathToken.class; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public boolean matches(Object model) { |
|
|
|
|
return true; |
|
|
|
|
return filterPathToken.accept(model, ctx.configuration()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} else if (target instanceof FilterPathToken) { |
|
|
|
|
return new Predicate() { |
|
|
|
|
private FilterPathToken filterPathToken = (FilterPathToken) target; |
|
|
|
|
|
|
|
|
|
private static final class WildcardPathTokenPredicate implements Predicate { |
|
|
|
|
@Override |
|
|
|
|
public Class<?> clazz() { |
|
|
|
|
return FilterPathToken.class; |
|
|
|
|
return WildcardPathToken.class; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public boolean matches(Object model) { |
|
|
|
|
return filterPathToken.accept(model, ctx.configuration()); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} else { |
|
|
|
|
return new Predicate() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static final class ArrayPathTokenPredicate implements Predicate { |
|
|
|
|
private final EvaluationContextImpl ctx; |
|
|
|
|
|
|
|
|
|
private ArrayPathTokenPredicate(EvaluationContextImpl ctx) { |
|
|
|
|
this.ctx = ctx; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Class<?> clazz() { |
|
|
|
|
return null; |
|
|
|
|
return ArrayPathToken.class; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public boolean matches(Object model) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
return ctx.jsonProvider().isArray(model); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static final class PropertyPathTokenPredicate implements Predicate { |
|
|
|
|
private final EvaluationContextImpl ctx; |
|
|
|
|
private PropertyPathToken propertyPathToken; |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
boolean isTokenDefinite() { |
|
|
|
|
return false; |
|
|
|
|
private PropertyPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { |
|
|
|
|
this.ctx = ctx; |
|
|
|
|
propertyPathToken = (PropertyPathToken) target; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public String getPathFragment() { |
|
|
|
|
return ".."; |
|
|
|
|
public Class<?> clazz() { |
|
|
|
|
return PropertyPathToken.class; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private interface Predicate { |
|
|
|
|
Class<?> clazz(); |
|
|
|
|
|
|
|
|
|
boolean matches(Object model); |
|
|
|
|
@Override |
|
|
|
|
public boolean matches(Object model) { |
|
|
|
|
Collection<String> keys = ctx.jsonProvider().getPropertyKeys(model); |
|
|
|
|
return keys.containsAll(propertyPathToken.getProperties()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|