Browse Source

Simplified scanning impl.

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

183
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()) {
next.evaluate(match.getKey(), match.getValue(), ctx);
}
} }
public static void walk(String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate, Map<String, Object> predicateMatches) { public static void walk(PathToken pt, String currentPath, Object model, EvaluationContextImpl ctx, Predicate predicate) {
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);
int idx = 0;
for (Object evalModel : models) {
String evalPath = currentPath + "[" + idx + "]";
next.evaluate(evalPath, evalModel, ctx);
idx++;
}
}
} }
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 + "]";
walk(pt, evalPath, evalModel, ctx, predicate);
if (predicate.clazz().equals(PredicatePathToken.class)) {
if (predicate.matches(evalModel)) {
predicateMatches.put(evalPath, evalModel);
}
}
walk(evalPath, evalModel, ctx, predicate, predicateMatches);
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,94 +116,69 @@ 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() { @Override
return null; public boolean matches(Object model) {
} return false;
}
@Override
public boolean matches(Object model) {
return false;
}
}; };
private static final class FilterPathTokenPredicate implements Predicate { private static final class FilterPathTokenPredicate implements Predicate {
private final EvaluationContextImpl ctx; private final EvaluationContextImpl ctx;
private PredicatePathToken predicatePathToken; private PredicatePathToken predicatePathToken;
private FilterPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { private FilterPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) {
this.ctx = ctx; this.ctx = ctx;
predicatePathToken = (PredicatePathToken) target; predicatePathToken = (PredicatePathToken) target;
} }
@Override @Override
public Class<?> clazz() { public boolean matches(Object model) {
return PredicatePathToken.class; return predicatePathToken.accept(model, ctx.rootDocument(), ctx.configuration(), ctx);
} }
@Override
public boolean matches(Object model) {
return predicatePathToken.accept(model, ctx.rootDocument(), ctx.configuration(), ctx);
}
} }
private static final class WildcardPathTokenPredicate implements Predicate { private static final class WildcardPathTokenPredicate implements Predicate {
@Override
public Class<?> clazz() { @Override
return WildcardPathToken.class; public boolean matches(Object model) {
} return true;
}
@Override
public boolean matches(Object model) {
return true;
}
} }
private static final class ArrayPathTokenPredicate implements Predicate { private static final class ArrayPathTokenPredicate implements Predicate {
private final EvaluationContextImpl ctx; private final EvaluationContextImpl ctx;
private ArrayPathTokenPredicate(EvaluationContextImpl ctx) { private ArrayPathTokenPredicate(EvaluationContextImpl ctx) {
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);
} }
} }
private static final class PropertyPathTokenPredicate implements Predicate { private static final class PropertyPathTokenPredicate implements Predicate {
private final EvaluationContextImpl ctx; private final EvaluationContextImpl ctx;
private PropertyPathToken propertyPathToken; private PropertyPathToken propertyPathToken;
private PropertyPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) { private PropertyPathTokenPredicate(PathToken target, EvaluationContextImpl ctx) {
this.ctx = ctx; this.ctx = ctx;
propertyPathToken = (PropertyPathToken) target; propertyPathToken = (PropertyPathToken) target;
} }
@Override @Override
public Class<?> clazz() { public boolean matches(Object model) {
return PropertyPathToken.class; if (ctx.jsonProvider().isMap(model)) {
} Collection<String> keys = ctx.jsonProvider().getPropertyKeys(model);
return keys.containsAll(propertyPathToken.getProperties());
@Override }
public boolean matches(Object model) { return false;
if(ctx.jsonProvider().isMap(model)){ }
Collection<String> keys = ctx.jsonProvider().getPropertyKeys(model);
return keys.containsAll(propertyPathToken.getProperties());
}
return false;
}
} }
} }

Loading…
Cancel
Save