Browse Source

merge JsonProvider's getMapValue methods, various small performance improvements

pull/47/head
Jochen Berger 10 years ago
parent
commit
2664f83104
  1. 6
      json-path/src/main/java/com/jayway/jsonpath/internal/compiler/PathToken.java
  2. 168
      json-path/src/main/java/com/jayway/jsonpath/internal/compiler/ScanPathToken.java
  3. 16
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/AbstractJsonProvider.java
  4. 12
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java

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

@ -69,12 +69,12 @@ public abstract class PathToken {
}
}
private boolean hasProperty(String property, Object model, EvaluationContextImpl ctx) {
private static boolean hasProperty(String property, Object model, EvaluationContextImpl ctx) {
return ctx.jsonProvider().getPropertyKeys(model).contains(property);
}
private Object readObjectProperty(String property, Object model, EvaluationContextImpl ctx) {
return ctx.jsonProvider().getMapValue(model, property, true);
private static Object readObjectProperty(String property, Object model, EvaluationContextImpl ctx) {
return ctx.jsonProvider().getMapValue(model, property);
}
void handleArrayIndex(int index, String currentPath, Object json, EvaluationContextImpl ctx) {

168
json-path/src/main/java/com/jayway/jsonpath/internal/compiler/ScanPathToken.java

@ -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,79 +81,24 @@ public class ScanPathToken extends PathToken {
for (String property : properties) {
String evalPath = currentPath + "['" + property + "']";
Object propertyModel = ctx.jsonProvider().getMapValue(model, property);
walk(evalPath, propertyModel, ctx, predicate, predicateMatches);
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;
@Override
public Class<?> clazz() {
return PropertyPathToken.class;
}
@Override
public boolean matches(Object model) {
Collection<String> keys = ctx.jsonProvider().getPropertyKeys(model);
return keys.containsAll(propertyPathToken.getProperties());
}
};
return new PropertyPathTokenPredicate(target, ctx);
} else if (target instanceof ArrayPathToken) {
return new Predicate() {
@Override
public Class<?> clazz() {
return ArrayPathToken.class;
}
@Override
public boolean matches(Object model) {
return ctx.jsonProvider().isArray(model);
}
};
return new ArrayPathTokenPredicate(ctx);
} else if (target instanceof WildcardPathToken) {
return new Predicate() {
@Override
public Class<?> clazz() {
return WildcardPathToken.class;
}
@Override
public boolean matches(Object model) {
return true;
}
};
return new WildcardPathTokenPredicate();
} else if (target instanceof FilterPathToken) {
return new Predicate() {
private FilterPathToken filterPathToken = (FilterPathToken) target;
@Override
public Class<?> clazz() {
return FilterPathToken.class;
}
@Override
public boolean matches(Object model) {
return filterPathToken.accept(model, ctx.configuration());
}
};
return new FilterPathTokenPredicate(target, ctx);
} else {
return new Predicate() {
@Override
public Class<?> clazz() {
return null;
}
@Override
public boolean matches(Object model) {
return false;
}
};
return FALSE_PREDICATE;
}
}
@ -165,10 +112,93 @@ public class ScanPathToken extends PathToken {
public String getPathFragment() {
return "..";
}
private interface Predicate {
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;
}
};
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 FilterPathToken.class;
}
@Override
public boolean matches(Object model) {
return filterPathToken.accept(model, ctx.configuration());
}
}
private static final class WildcardPathTokenPredicate implements Predicate {
@Override
public Class<?> clazz() {
return WildcardPathToken.class;
}
@Override
public boolean matches(Object model) {
return true;
}
}
private static final class ArrayPathTokenPredicate implements Predicate {
private final EvaluationContextImpl ctx;
private ArrayPathTokenPredicate(EvaluationContextImpl ctx) {
this.ctx = ctx;
}
@Override
public Class<?> clazz() {
return ArrayPathToken.class;
}
@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) {
Collection<String> keys = ctx.jsonProvider().getPropertyKeys(model);
return keys.containsAll(propertyPathToken.getProperties());
}
}
}

16
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/AbstractJsonProvider.java

@ -50,23 +50,11 @@ public abstract class AbstractJsonProvider implements JsonProvider {
*
* @param obj a map
* @param key property key
* @return the map entry
* @return the map entry or {@link com.jayway.jsonpath.spi.json.JsonProvider#UNDEFINED} for missing properties
*/
public Object getMapValue(Object obj, String key){
return ((Map) obj).get(key);
}
/**
* Extracts a value from an map
*
* @param obj a map
* @param key property key
* @param signalUndefined if true the constant {@link com.jayway.jsonpath.spi.json.JsonProvider#UNDEFINED} is returned for missing properties
* @return the map entry
*/
public Object getMapValue(Object obj, String key, boolean signalUndefined){
Map m = (Map) obj;
if(!m.containsKey(key) && signalUndefined){
if(!m.containsKey(key)){
return JsonProvider.UNDEFINED;
} else {
return m.get(key);

12
json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java

@ -83,20 +83,10 @@ public interface JsonProvider {
*
* @param obj a map
* @param key property key
* @return the map entry
* @return the map entry or {@link com.jayway.jsonpath.spi.json.JsonProvider#UNDEFINED} for missing properties
*/
Object getMapValue(Object obj, String key);
/**
* Extracts a value from an map
*
* @param obj a map
* @param key property key
* @param signalUndefined if true the constant {@link com.jayway.jsonpath.spi.json.JsonProvider#UNDEFINED} is returned for missing properties
* @return the map entry
*/
Object getMapValue(Object obj, String key, boolean signalUndefined);
/**
* Sets a value in an object or array
*

Loading…
Cancel
Save