From ecc4631a0da265fc647153fda348540889eae1dc Mon Sep 17 00:00:00 2001 From: Kalle Stenflo Date: Wed, 22 Oct 2014 18:40:50 +0200 Subject: [PATCH] Simplified scanning impl. --- .../internal/token/ScanPathToken.java | 183 +++++++----------- 1 file changed, 73 insertions(+), 110 deletions(-) diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/token/ScanPathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/token/ScanPathToken.java index 1e591d9d..a6387198 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/token/ScanPathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/token/ScanPathToken.java @@ -17,8 +17,6 @@ package com.jayway.jsonpath.internal.token; import com.jayway.jsonpath.spi.json.JsonProvider; import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; /** * @@ -32,74 +30,64 @@ public class ScanPathToken extends PathToken { ctx.addResult(currentPath, model); } - Predicate predicate = createScanPredicate(next(), ctx); - Map predicateMatches = new LinkedHashMap(); + PathToken pt = next(); - walk(currentPath, model, ctx, predicate, predicateMatches); - - //Filters has already been evaluated - PathToken next = next(); - if (next instanceof PredicatePathToken) { - if (next.isLeaf()) { - for (Map.Entry match : predicateMatches.entrySet()) { - ctx.addResult(match.getKey(), match.getValue()); - } - return; - } else { - next = next.next(); - } - } - - for (Map.Entry match : predicateMatches.entrySet()) { - next.evaluate(match.getKey(), match.getValue(), ctx); - } + walk(pt, currentPath, model, ctx, createScanPredicate(pt, ctx)); } - public static void walk(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map predicateMatches) { + public static void walk(PathToken pt, String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate) { if (ctx.jsonProvider().isMap(model)) { - walkObject(currentPath, model, ctx, predicate, predicateMatches); + walkObject(pt, currentPath, model, ctx, predicate); } else if (ctx.jsonProvider().isArray(model)) { - walkArray(currentPath, model, ctx, predicate, predicateMatches); + walkArray(pt, currentPath, model, ctx, predicate); } } - public static void walkArray(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map predicateMatches) { + public static void walkArray(PathToken pt, String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate) { if (predicate.matches(model)) { - predicateMatches.put(currentPath, model); + if (pt.isLeaf()) { + pt.evaluate(currentPath, model, ctx); + } else { + PathToken next = pt.next(); + Iterable models = ctx.jsonProvider().toIterable(model); + int idx = 0; + for (Object evalModel : models) { + String evalPath = currentPath + "[" + idx + "]"; + next.evaluate(evalPath, evalModel, ctx); + idx++; + } + } } Iterable models = ctx.jsonProvider().toIterable(model); int idx = 0; for (Object evalModel : models) { String evalPath = currentPath + "[" + idx + "]"; - - if (predicate.clazz().equals(PredicatePathToken.class)) { - if (predicate.matches(evalModel)) { - predicateMatches.put(evalPath, evalModel); - } - } - - walk(evalPath, evalModel, ctx, predicate, predicateMatches); + walk(pt, evalPath, evalModel, ctx, predicate); idx++; } } - public static void walkObject(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map predicateMatches) { + public static void walkObject(PathToken pt, String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate) { if (predicate.matches(model)) { - predicateMatches.put(currentPath, model); + if (pt.isLeaf()) { + pt.evaluate(currentPath, model, ctx); + } else { + pt.evaluate(currentPath, model, ctx); + } } Collection properties = ctx.jsonProvider().getPropertyKeys(model); + 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); + walk(pt, evalPath, propertyModel, ctx, predicate); } } - } private static Predicate createScanPredicate(final PathToken target, final EvaluationContextImpl ctx) { @@ -128,94 +116,69 @@ public class ScanPathToken extends PathToken { } private static interface Predicate { - Class clazz(); - boolean matches(Object model); } private static final Predicate FALSE_PREDICATE = new Predicate() { - @Override - public Class clazz() { - return null; - } - - @Override - public boolean matches(Object model) { - return false; - } + + @Override + public boolean matches(Object model) { + return false; + } }; private static final class FilterPathTokenPredicate implements Predicate { - private final EvaluationContextImpl ctx; - private PredicatePathToken predicatePathToken; - - private FilterPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { - this.ctx = ctx; - predicatePathToken = (PredicatePathToken) target; - } - - @Override - public Class clazz() { - return PredicatePathToken.class; - } - - @Override - public boolean matches(Object model) { - return predicatePathToken.accept(model, ctx.rootDocument(), ctx.configuration(), ctx); - } + private final EvaluationContextImpl ctx; + private PredicatePathToken predicatePathToken; + + private FilterPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { + this.ctx = ctx; + predicatePathToken = (PredicatePathToken) target; + } + + @Override + public boolean matches(Object model) { + return predicatePathToken.accept(model, ctx.rootDocument(), ctx.configuration(), ctx); + } } private static final class WildcardPathTokenPredicate implements Predicate { - @Override - public Class clazz() { - return WildcardPathToken.class; - } - - @Override - public boolean matches(Object model) { - return true; - } + + @Override + public boolean matches(Object model) { + return true; + } } private static final class ArrayPathTokenPredicate implements Predicate { - private final EvaluationContextImpl ctx; + private final EvaluationContextImpl ctx; - private ArrayPathTokenPredicate(EvaluationContextImpl ctx) { - this.ctx = ctx; - } - - @Override - public Class clazz() { - return ArrayPathToken.class; - } + private ArrayPathTokenPredicate(EvaluationContextImpl ctx) { + this.ctx = ctx; + } - @Override - public boolean matches(Object model) { - return ctx.jsonProvider().isArray(model); - } + @Override + public boolean matches(Object model) { + return ctx.jsonProvider().isArray(model); + } } private static final class PropertyPathTokenPredicate implements Predicate { - private final EvaluationContextImpl ctx; - private PropertyPathToken propertyPathToken; - - private PropertyPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { - this.ctx = ctx; - propertyPathToken = (PropertyPathToken) target; - } - - @Override - public Class clazz() { - return PropertyPathToken.class; - } - - @Override - public boolean matches(Object model) { - if(ctx.jsonProvider().isMap(model)){ - Collection keys = ctx.jsonProvider().getPropertyKeys(model); - return keys.containsAll(propertyPathToken.getProperties()); - } - return false; - } + private final EvaluationContextImpl ctx; + private PropertyPathToken propertyPathToken; + + private PropertyPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { + this.ctx = ctx; + propertyPathToken = (PropertyPathToken) target; + } + + @Override + public boolean matches(Object model) { + if (ctx.jsonProvider().isMap(model)) { + Collection keys = ctx.jsonProvider().getPropertyKeys(model); + return keys.containsAll(propertyPathToken.getProperties()); + } + return false; + } } }