Browse Source

Simplified scanning impl.

pull/58/merge
Kalle Stenflo 10 years ago
parent
commit
ecc4631a0d
  1. 89
      json-path/src/main/java/com/jayway/jsonpath/internal/token/ScanPathToken.java

89
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 com.jayway.jsonpath.spi.json.JsonProvider;
import java.util.Collection; 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); ctx.addResult(currentPath, model);
} }
Predicate predicate = createScanPredicate(next(), ctx); PathToken pt = next();
Map<String, Object> predicateMatches = new LinkedHashMap<String, Object>();
walk(currentPath, model, ctx, predicate, predicateMatches); walk(pt, currentPath, model, ctx, createScanPredicate(pt, ctx));
//Filters has already been evaluated
PathToken next = next();
if (next instanceof PredicatePathToken) {
if (next.isLeaf()) {
for (Map.Entry<String, Object> match : predicateMatches.entrySet()) {
ctx.addResult(match.getKey(), match.getValue());
}
return;
} else {
next = next.next();
}
} }
for (Map.Entry<String, Object> match : predicateMatches.entrySet()) { public static void walk(PathToken pt, String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate) {
next.evaluate(match.getKey(), match.getValue(), ctx);
}
}
public static void walk(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) {
if (ctx.jsonProvider().isMap(model)) { if (ctx.jsonProvider().isMap(model)) {
walkObject(currentPath, model, ctx, predicate, predicateMatches); walkObject(pt, currentPath, model, ctx, predicate);
} else if (ctx.jsonProvider().isArray(model)) { } 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<String, Object> predicateMatches) { public static void walkArray(PathToken pt, String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate) {
if (predicate.matches(model)) { 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); Iterable<?> models = ctx.jsonProvider().toIterable(model);
int idx = 0; int idx = 0;
for (Object evalModel : models) { for (Object evalModel : models) {
String evalPath = currentPath + "[" + idx + "]"; String evalPath = currentPath + "[" + idx + "]";
next.evaluate(evalPath, evalModel, ctx);
if (predicate.clazz().equals(PredicatePathToken.class)) { idx++;
if (predicate.matches(evalModel)) { }
predicateMatches.put(evalPath, evalModel);
} }
} }
walk(evalPath, evalModel, ctx, predicate, predicateMatches); Iterable<?> models = ctx.jsonProvider().toIterable(model);
int idx = 0;
for (Object evalModel : models) {
String evalPath = currentPath + "[" + idx + "]";
walk(pt, evalPath, evalModel, ctx, predicate);
idx++; idx++;
} }
} }
public static void walkObject(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { public static void walkObject(PathToken pt, String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate) {
if (predicate.matches(model)) { if (predicate.matches(model)) {
predicateMatches.put(currentPath, model); if (pt.isLeaf()) {
pt.evaluate(currentPath, model, ctx);
} else {
pt.evaluate(currentPath, model, ctx);
}
} }
Collection<String> properties = ctx.jsonProvider().getPropertyKeys(model); Collection<String> properties = ctx.jsonProvider().getPropertyKeys(model);
for (String property : properties) { for (String property : properties) {
String evalPath = currentPath + "['" + property + "']"; String evalPath = currentPath + "['" + property + "']";
Object propertyModel = ctx.jsonProvider().getMapValue(model, property); Object propertyModel = ctx.jsonProvider().getMapValue(model, property);
if (propertyModel != JsonProvider.UNDEFINED) { 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) { private static Predicate createScanPredicate(final PathToken target, final EvaluationContextImpl ctx) {
@ -128,16 +116,10 @@ public class ScanPathToken extends PathToken {
} }
private static interface Predicate { private static interface Predicate {
Class<?> clazz();
boolean matches(Object model); boolean matches(Object model);
} }
private static final Predicate FALSE_PREDICATE = new Predicate() { private static final Predicate FALSE_PREDICATE = new Predicate() {
@Override
public Class<?> clazz() {
return null;
}
@Override @Override
public boolean matches(Object model) { public boolean matches(Object model) {
@ -154,11 +136,6 @@ public class ScanPathToken extends PathToken {
predicatePathToken = (PredicatePathToken) target; predicatePathToken = (PredicatePathToken) target;
} }
@Override
public Class<?> clazz() {
return PredicatePathToken.class;
}
@Override @Override
public boolean matches(Object model) { public boolean matches(Object model) {
return predicatePathToken.accept(model, ctx.rootDocument(), ctx.configuration(), ctx); return predicatePathToken.accept(model, ctx.rootDocument(), ctx.configuration(), ctx);
@ -166,10 +143,6 @@ public class ScanPathToken extends PathToken {
} }
private static final class WildcardPathTokenPredicate implements Predicate { private static final class WildcardPathTokenPredicate implements Predicate {
@Override
public Class<?> clazz() {
return WildcardPathToken.class;
}
@Override @Override
public boolean matches(Object model) { public boolean matches(Object model) {
@ -184,11 +157,6 @@ public class ScanPathToken extends PathToken {
this.ctx = ctx; this.ctx = ctx;
} }
@Override
public Class<?> clazz() {
return ArrayPathToken.class;
}
@Override @Override
public boolean matches(Object model) { public boolean matches(Object model) {
return ctx.jsonProvider().isArray(model); return ctx.jsonProvider().isArray(model);
@ -204,11 +172,6 @@ public class ScanPathToken extends PathToken {
propertyPathToken = (PropertyPathToken) target; propertyPathToken = (PropertyPathToken) target;
} }
@Override
public Class<?> clazz() {
return PropertyPathToken.class;
}
@Override @Override
public boolean matches(Object model) { public boolean matches(Object model) {
if (ctx.jsonProvider().isMap(model)) { if (ctx.jsonProvider().isMap(model)) {

Loading…
Cancel
Save