Browse Source

Improved Filter and Criteria.

pull/8/merge
Kalle Stenflo 13 years ago
parent
commit
89b74987ba
  1. 354
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  2. 28
      json-path/src/main/java/com/jayway/jsonpath/Filter.java
  3. 7
      json-path/src/main/java/com/jayway/jsonpath/JsonModel.java
  4. 4
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java
  5. 1
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.java
  6. 21
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterFactory.java
  7. 3
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathTokenFilter.java
  8. 24
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/eval/ExpressionEvaluator.java
  9. 33
      json-path/src/main/java/com/jayway/jsonpath/spi/impl/AbstractJsonProvider.java
  10. 1
      json-path/src/main/java/com/jayway/jsonpath/spi/impl/JacksonProvider.java
  11. 4
      json-path/src/main/java/com/jayway/jsonpath/spi/impl/JsonSmartJsonProvider.java
  12. 44
      json-path/src/test/java/com/jayway/jsonpath/FilterTest.java
  13. 14
      pom.xml

354
json-path/src/main/java/com/jayway/jsonpath/Criteria.java

@ -32,23 +32,39 @@ public class Criteria {
*/
private static final Object NOT_SET = new Object();
private String key;
private enum CriteriaType {
GT,
GTE,
LT,
LTE,
NE,
IN,
NIN,
ALL,
SIZE,
EXISTS,
TYPE,
REGEX,
OR
}
private final String key;
private List<Criteria> criteriaChain;
private final List<Criteria> criteriaChain;
private LinkedHashMap<String, Object> criteria = new LinkedHashMap<String, Object>();
private final LinkedHashMap<CriteriaType, Object> criteria = new LinkedHashMap<CriteriaType, Object>();
private Object isValue = NOT_SET;
public Criteria(String key) {
private Criteria(String key) {
notEmpty(key, "key can not be null or empty");
this.criteriaChain = new ArrayList<Criteria>();
this.criteriaChain.add(this);
this.key = key;
}
protected Criteria(List<Criteria> criteriaChain, String key) {
private Criteria(List<Criteria> criteriaChain, String key) {
notEmpty(key, "key can not be null or empty");
this.criteriaChain = criteriaChain;
this.criteriaChain.add(this);
@ -59,14 +75,20 @@ public class Criteria {
return this.key;
}
public boolean apply(Map<String, Object> map) {
/**
* Checks if this criteria matches the given map
*
* @param map map to check
* @return true if criteria is a match
*/
public boolean matches(Map<String, Object> map) {
if (this.criteriaChain.size() == 1) {
return criteriaChain.get(0).singleObjectApply(map);
} else {
for (Criteria c : this.criteriaChain) {
System.out.println("");
if (!c.singleObjectApply(map)) {
return false;
}
@ -75,150 +97,152 @@ public class Criteria {
}
}
protected boolean singleObjectApply(Map<String, Object> map) {
boolean not = false;
for (String key : this.criteria.keySet()) {
Object expectedVal = null;
Object actualVal = map.get(this.key);
if (not) {
expectedVal = this.criteria.get(key);
not = false;
} else {
if ("$not".equals(key)) {
not = true;
} else {
expectedVal = this.criteria.get(key);
if ("$gt".equals(key)) {
if (expectedVal == null || actualVal == null) {
return false;
}
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
return (actualNumber.doubleValue() > expectedNumber.doubleValue());
boolean singleObjectApply(Map<String, Object> map) {
} else if ("$gte".equals(key)) {
for (CriteriaType key : this.criteria.keySet()) {
if (expectedVal == null || actualVal == null) {
return false;
}
Object actualVal = map.get(this.key);
Object expectedVal = this.criteria.get(key);
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
if (CriteriaType.GT.equals(key)) {
return (actualNumber.doubleValue() >= expectedNumber.doubleValue());
if (expectedVal == null || actualVal == null) {
return false;
}
} else if ("$lt".equals(key)) {
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
if (expectedVal == null || actualVal == null) {
return false;
}
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
return (actualNumber.doubleValue() > expectedNumber.doubleValue());
return (actualNumber.doubleValue() < expectedNumber.doubleValue());
} else if (CriteriaType.GTE.equals(key)) {
} else if ("$lte".equals(key)) {
if (expectedVal == null || actualVal == null) {
return false;
}
if (expectedVal == null || actualVal == null) {
return false;
}
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
return (actualNumber.doubleValue() >= expectedNumber.doubleValue());
return (actualNumber.doubleValue() <= expectedNumber.doubleValue());
} else if (CriteriaType.LT.equals(key)) {
} else if ("$ne".equals(key)) {
if (expectedVal == null && actualVal == null) {
return false;
}
if (expectedVal == null) {
return !(actualVal == null);
}
if (expectedVal == null || actualVal == null) {
return false;
}
return !expectedVal.equals(actualVal);
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
} else if ("$in".equals(key)) {
return (actualNumber.doubleValue() < expectedNumber.doubleValue());
Collection exp = (Collection) expectedVal;
} else if (CriteriaType.LTE.equals(key)) {
return exp.contains(actualVal);
if (expectedVal == null || actualVal == null) {
return false;
}
} else if ("$nin".equals(key)) {
Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal;
Collection exp = (Collection) expectedVal;
return (actualNumber.doubleValue() <= expectedNumber.doubleValue());
return !exp.contains(actualVal);
} else if ("$all".equals(key)) {
} else if (CriteriaType.NE.equals(key)) {
if (expectedVal == null && actualVal == null) {
return false;
}
if (expectedVal == null) {
return true;
} else {
return !expectedVal.equals(actualVal);
}
Collection exp = (Collection) expectedVal;
Collection act = (Collection) actualVal;
} else if (CriteriaType.IN.equals(key)) {
return act.containsAll(exp);
Collection exp = (Collection) expectedVal;
} else if ("$size".equals(key)) {
return exp.contains(actualVal);
int exp = (Integer) expectedVal;
List act = (List) actualVal;
} else if (CriteriaType.NIN.equals(key)) {
return (act.size() == exp);
Collection exp = (Collection) expectedVal;
} else if ("$exists".equals(key)) {
return !exp.contains(actualVal);
} else if (CriteriaType.ALL.equals(key)) {
boolean exp = (Boolean) expectedVal;
boolean act = map.containsKey(this.key);
Collection exp = (Collection) expectedVal;
Collection act = (Collection) actualVal;
return act == exp;
return act.containsAll(exp);
} else if ("$type".equals(key)) {
} else if (CriteriaType.SIZE.equals(key)) {
Class<?> exp = (Class<?>) expectedVal;
Class<?> act = null;
if (map.containsKey(this.key)) {
Object actVal = map.get(this.key);
if (actVal != null) {
act = actVal.getClass();
}
}
if (act == null) {
return false;
} else {
return act.equals(exp);
}
int exp = (Integer) expectedVal;
List act = (List) actualVal;
} else if ("$regex".equals(key)) {
return (act.size() == exp);
} else if (CriteriaType.EXISTS.equals(key)) {
Pattern exp = (Pattern) expectedVal;
String act = (String) actualVal;
if(act == null){
return false;
}
return exp.matcher(act).matches();
boolean exp = (Boolean) expectedVal;
boolean act = map.containsKey(this.key);
} else if ("$or".equals(key)) {
return act == exp;
} else if (CriteriaType.TYPE.equals(key)) {
throw new UnsupportedOperationException("Or not supported yet");
Class<?> exp = (Class<?>) expectedVal;
Class<?> act = null;
if (map.containsKey(this.key)) {
Object actVal = map.get(this.key);
if (actVal != null) {
act = actVal.getClass();
}
}
if (act == null) {
return false;
} else {
return act.equals(exp);
}
} else if (CriteriaType.REGEX.equals(key)) {
}
Pattern exp = (Pattern) expectedVal;
String act = (String) actualVal;
if (act == null) {
return false;
}
return exp.matcher(act).matches();
} else {
throw new UnsupportedOperationException("Criteria type not supported: " + key.name());
}
}
if (isValue != NOT_SET) {
if (isValue == null) {
return (map.get(key) == null);
if (isValue instanceof Collection) {
Collection<Criteria> cs = (Collection<Criteria>) isValue;
for (Criteria crit : cs) {
for (Criteria c : crit.criteriaChain) {
if (!c.singleObjectApply(map)) {
return false;
}
}
}
return true;
} else {
return isValue.equals(map.get(key));
if (isValue == null) {
return (map.get(key) == null);
} else {
return isValue.equals(map.get(key));
}
}
} else {
@ -230,8 +254,8 @@ public class Criteria {
/**
* Static factory method to create a Criteria using the provided key
*
* @param key
* @return
* @param key filed name
* @return the new criteria
*/
public static Criteria where(String key) {
@ -241,7 +265,8 @@ public class Criteria {
/**
* Static factory method to create a Criteria using the provided key
*
* @return
* @param key ads new filed to criteria
* @return the criteria builder
*/
public Criteria and(String key) {
return new Criteria(this.criteriaChain, key);
@ -264,6 +289,7 @@ public class Criteria {
this.isValue = o;
return this;
}
/**
* Creates a criterion using equality
*
@ -275,62 +301,63 @@ public class Criteria {
}
/**
* Creates a criterion using the $ne operator
* Creates a criterion using the <b>!=</b> operator
*
* @param o
* @return
*/
public Criteria ne(Object o) {
criteria.put("$ne", o);
criteria.put(CriteriaType.NE, o);
return this;
}
/**
* Creates a criterion using the $lt operator
* Creates a criterion using the <b>&lt;</b> operator
*
* @param o
* @return
*/
public Criteria lt(Object o) {
criteria.put("$lt", o);
criteria.put(CriteriaType.LT, o);
return this;
}
/**
* Creates a criterion using the $lte operator
* Creates a criterion using the <b>&lt;=</b> operator
*
* @param o
* @return
*/
public Criteria lte(Object o) {
criteria.put("$lte", o);
criteria.put(CriteriaType.LTE, o);
return this;
}
/**
* Creates a criterion using the $gt operator
* Creates a criterion using the <b>&gt;</b> operator
*
* @param o
* @return
*/
public Criteria gt(Object o) {
criteria.put("$gt", o);
criteria.put(CriteriaType.GT, o);
return this;
}
/**
* Creates a criterion using the $gte operator
* Creates a criterion using the <b>&gt;=</b> operator
*
* @param o
* @return
*/
public Criteria gte(Object o) {
criteria.put("$gte", o);
criteria.put(CriteriaType.GTE, o);
return this;
}
/**
* Creates a criterion using the $in operator
* The <code>in</code> operator is analogous to the SQL IN modifier, allowing you
* to specify an array of possible matches.
*
* @param o the values to match against
* @return
@ -344,35 +371,45 @@ public class Criteria {
}
/**
* Creates a criterion using the $in operator
*
* @param c the collection containing the values to match against
* @return
*/
* The <code>in</code> operator is analogous to the SQL IN modifier, allowing you
* to specify an array of possible matches.
*
* @param c the collection containing the values to match against
* @return
*/
public Criteria in(Collection<?> c) {
criteria.put("$in", c);
notNull(c, "collection can not be null");
criteria.put(CriteriaType.IN, c);
return this;
}
/**
* Creates a criterion using the $nin operator
* The <code>nin</code> operator is similar to $in except that it selects objects for
* which the specified field does not have any value in the specified array.
*
* @param o
* @param o the values to match against
* @return
*/
public Criteria nin(Object... o) {
return nin(Arrays.asList(o));
}
public Criteria nin(Collection<?> o) {
notNull(o, "collection can not be null");
criteria.put("$nin", o);
/**
* The <code>nin</code> operator is similar to $in except that it selects objects for
* which the specified field does not have any value in the specified array.
*
* @param c the values to match against
* @return
*/
public Criteria nin(Collection<?> c) {
notNull(c, "collection can not be null");
criteria.put(CriteriaType.NIN, c);
return this;
}
/**
* Creates a criterion using the $all operator
* The <code>all</code> operator is similar to $in, but instead of matching any value in the specified array all values in the array must be matched.
*
* @param o
* @return
@ -380,94 +417,77 @@ public class Criteria {
public Criteria all(Object... o) {
return all(Arrays.asList(o));
}
public Criteria all(Collection<?> o) {
criteria.put("$all", o);
/**
* The <code>all</code> operator is similar to $in, but instead of matching any value in the specified array all values in the array must be matched.
*
* @param c
* @return
*/
public Criteria all(Collection<?> c) {
notNull(c, "collection can not be null");
criteria.put(CriteriaType.ALL, c);
return this;
}
/**
* Creates a criterion using the $size operator
* The <code>size</code> operator matches any array with the specified number of elements.
*
* @param s
* @return
*/
public Criteria size(int s) {
criteria.put("$size", s);
criteria.put(CriteriaType.SIZE, s);
return this;
}
/**
* Creates a criterion using the $exists operator
* Check for existence (or lack thereof) of a field.
*
* @param b
* @return
*/
public Criteria exists(boolean b) {
criteria.put("$exists", b);
criteria.put(CriteriaType.EXISTS, b);
return this;
}
/**
* Creates a criterion using the $type operator
* The $type operator matches values based on their Java type.
*
* @param t
* @return
*/
public Criteria type(Class<?> t) {
criteria.put("$type", t);
return this;
}
/**
* Creates a criterion using the $not meta operator which affects the clause directly following
*
* @return
*/
public Criteria not() {
criteria.put("$not", null);
notNull(t, "type can not be null");
criteria.put(CriteriaType.TYPE, t);
return this;
}
/**
* Creates a criterion using a $regex and $options
* Creates a criterion using a Regex
*
* @param pattern
* @return
*/
public Criteria regex(Pattern pattern) {
criteria.put("$regex", pattern);
notNull(pattern, "pattern can not be null");
criteria.put(CriteriaType.REGEX, pattern);
return this;
}
/**
* Creates a criterion using the $mod operator
*
* @param value
* @param remainder
* @return
*/
/*
public Criteria mod(Number value, Number remainder) {
List<Object> l = new ArrayList<Object>();
l.add(value);
l.add(remainder);
criteria.put("$mod", l);
return this;
}
*/
/**
* Creates an 'or' criteria using the $or operator for all of the provided criteria
*
* @param criteria
*/
/*
public Criteria orOperator(Criteria... criteria) {
criteriaChain.add(new Criteria("$or").is(asList(criteria)));
return this;
}
*/
/**
* Creates a 'nor' criteria using the $nor operator for all of the provided criteria

28
json-path/src/main/java/com/jayway/jsonpath/Filter.java

@ -27,16 +27,26 @@ import java.util.*;
* List<String> names = JsonPath.read(doc, "$items[?].name", Filter.filter(Criteria.where("name").is("john"));
* </code>
*
* @See Criteria
* @see Criteria
*
* @author Kalle Stenflo
*/
public abstract class Filter<T> {
/**
* Creates a new filter based on given criteria
* @param criteria the filter criteria
* @return a new filter
*/
public static Filter filter(Criteria criteria) {
return new MapFilter(criteria);
}
/**
* Filters the provided list based on this filter configuration
* @param filterItems items to filter
* @return the filtered list
*/
public List<T> doFilter(List<T> filterItems) {
List<T> result = new ArrayList<T>();
for (T filterItem : filterItems) {
@ -47,9 +57,19 @@ public abstract class Filter<T> {
return result;
}
/**
* Check if this filter will accept or reject the given object
* @param obj item to check
* @return true if filter matches
*/
public abstract boolean accept(T obj);
/**
* Adds a new criteria to this filter
*
* @param criteria to add
* @return the updated filter
*/
public abstract Filter addCriteria(Criteria criteria);
@ -94,7 +114,7 @@ public abstract class Filter<T> {
@Override
public boolean accept(Map<String, Object> map) {
for (Criteria criterion : this.criteria.values()) {
if (!criterion.apply(map)) {
if (!criterion.matches(map)) {
return false;
}
}

7
json-path/src/main/java/com/jayway/jsonpath/JsonModel.java

@ -58,6 +58,7 @@ public class JsonModel {
* Note that the jsonObject must either a {@link List} or a {@link Map}
*
* @param jsonObject the json object
* @param jsonProvider
*/
private JsonModel(Object jsonObject, JsonProvider jsonProvider) {
notNull(jsonObject, "json can not be null");
@ -73,6 +74,7 @@ public class JsonModel {
* Creates a new JsonModel based on an {@link InputStream}
*
* @param jsonInputStream the input stream
* @param jsonProvider
*/
private JsonModel(InputStream jsonInputStream, JsonProvider jsonProvider) {
notNull(jsonInputStream, "jsonInputStream can not be null");
@ -84,7 +86,8 @@ public class JsonModel {
* Creates a new JsonModel by fetching the content from the provided URL
*
* @param jsonURL the URL to read
* @throws IOException
* @param jsonProvider
* @throws IOException failed to load URL
*/
private JsonModel(URL jsonURL, JsonProvider jsonProvider) throws IOException {
notNull(jsonURL, "jsonURL can not be null");
@ -266,7 +269,7 @@ public class JsonModel {
} while (!tokens.isEmpty());
if (modelRef.getClass().isAssignableFrom(clazz)) {
throw new InvalidModelPathException(jsonPath + " does nor refer to a Map but " + (currentToken != null ? currentToken.getClass().getName() : "null"));
throw new InvalidModelPathException(jsonPath + " does nor refer to a Map but " + currentToken.getClass().getName());
}
return clazz.cast(modelRef);
}

4
json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java

@ -102,8 +102,8 @@ public class ArrayEvalFilter extends PathTokenFilter {
}
private class ConditionStatement {
private String field;
private String operator;
private final String field;
private final String operator;
private String expected;
private ConditionStatement(String field, String operator, String expected) {

1
json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.java

@ -19,7 +19,6 @@ import com.jayway.jsonpath.spi.JsonProvider;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author Kalle Stenflo

21
json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterFactory.java

@ -23,14 +23,15 @@ public class FilterFactory {
private final static PathTokenFilter ALL_ARRAY_ITEMS_FILTER = new PassthroughFilter("[*]", true);
private final static PathTokenFilter WILDCARD_FILTER = new WildcardFilter("*");
private final static PathTokenFilter SCAN_FILTER = new ScanFilter("..");
private final static PathTokenFilter ARRAY_QUERY_FILTER = new ArrayQueryFilter("[?]");
public static PathTokenFilter createFilter(String pathFragment) {
if ("$".equals(pathFragment)) {
if (DOCUMENT_FILTER.getCondition().equals(pathFragment)) { //"$"
return DOCUMENT_FILTER;
} else if("[*]".equals(pathFragment)){
} else if (ALL_ARRAY_ITEMS_FILTER.getCondition().equals(pathFragment)) { //"[*]"
return ALL_ARRAY_ITEMS_FILTER;
@ -38,22 +39,23 @@ public class FilterFactory {
return WILDCARD_FILTER;
} else if (pathFragment.contains("..")) {
//} else if (pathFragment.contains("..")) {
} else if (SCAN_FILTER.getCondition().equals(pathFragment)) {
return SCAN_FILTER;
} else if (!pathFragment.contains("[")) {
} else if (ARRAY_QUERY_FILTER.getCondition().equals(pathFragment)) { //"[?]"
return new FieldFilter(pathFragment);
return ARRAY_QUERY_FILTER;
} else if (pathFragment.equals("[?]")) {
} else if (!pathFragment.contains("[")) {
return new ArrayQueryFilter(pathFragment);
return new FieldFilter(pathFragment);
} else if (pathFragment.contains("[")) {
if (pathFragment.startsWith("[?")) {
if(!pathFragment.contains("=") && !pathFragment.contains("<") && !pathFragment.contains(">")){
if (!pathFragment.contains("=") && !pathFragment.contains("<") && !pathFragment.contains(">")) {
//[?(@.isbn)]
return new HasFieldFilter(pathFragment);
} else {
@ -69,10 +71,9 @@ public class FilterFactory {
}
}
throw new UnsupportedOperationException("..");
throw new UnsupportedOperationException("can not find filter for path fragment " + pathFragment);
}
}

3
json-path/src/main/java/com/jayway/jsonpath/internal/filter/PathTokenFilter.java

@ -30,6 +30,9 @@ public abstract class PathTokenFilter {
this.condition = condition;
}
String getCondition() {
return condition;
}
String trim(String str, int front, int end) {
String res = str;

24
json-path/src/main/java/com/jayway/jsonpath/internal/filter/eval/ExpressionEvaluator.java

@ -31,13 +31,13 @@ public class ExpressionEvaluator {
} else if ("!=".equals(comparator) || "<>".equals(comparator)) {
return a.longValue() != e.longValue();
} else if (">".equals(comparator)) {
return a.longValue() > e.longValue();
return a > e;
} else if (">=".equals(comparator)) {
return a.longValue() >= e.longValue();
return a >= e;
} else if ("<".equals(comparator)) {
return a.longValue() < e.longValue();
return a < e;
} else if ("<=".equals(comparator)) {
return a.longValue() <= e.longValue();
return a <= e;
}
} else if (actual instanceof Integer) {
Integer a = (Integer) actual;
@ -48,13 +48,13 @@ public class ExpressionEvaluator {
} else if ("!=".equals(comparator) || "<>".equals(comparator)) {
return a.intValue() != e.intValue();
} else if (">".equals(comparator)) {
return a.intValue() > e.intValue();
return a > e;
} else if (">=".equals(comparator)) {
return a.intValue() >= e.intValue();
return a >= e;
} else if ("<".equals(comparator)) {
return a.intValue() < e.intValue();
return a < e;
} else if ("<=".equals(comparator)) {
return a.intValue() <= e.intValue();
return a <= e;
}
} else if (actual instanceof Double) {
@ -66,13 +66,13 @@ public class ExpressionEvaluator {
} else if ("!=".equals(comparator) || "<>".equals(comparator)) {
return a.doubleValue() != e.doubleValue();
} else if (">".equals(comparator)) {
return a.doubleValue() > e.doubleValue();
return a > e;
} else if (">=".equals(comparator)) {
return a.doubleValue() >= e.doubleValue();
return a >= e;
} else if ("<".equals(comparator)) {
return a.doubleValue() < e.doubleValue();
return a < e;
} else if ("<=".equals(comparator)) {
return a.doubleValue() <= e.doubleValue();
return a <= e;
}
} else if (actual instanceof String) {

33
json-path/src/main/java/com/jayway/jsonpath/spi/impl/AbstractJsonProvider.java

@ -1,3 +1,17 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.spi.impl;
import com.jayway.jsonpath.spi.JsonProvider;
@ -6,10 +20,7 @@ import java.util.List;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 3/2/12
* Time: 9:56 PM
* @author Kalle Stenflo
*/
public abstract class AbstractJsonProvider implements JsonProvider {
@ -36,8 +47,8 @@ public abstract class AbstractJsonProvider implements JsonProvider {
/**
* Converts give object to a List
*
* @param list
* @return
* @param list object to convert
* @return object as list
*/
@SuppressWarnings({"unchecked"})
public List<Object> toList(Object list) {
@ -48,8 +59,8 @@ public abstract class AbstractJsonProvider implements JsonProvider {
/**
* Converts given object to a Map
*
* @param map
* @return
* @param map object to convert
* @return object as map
*/
@SuppressWarnings({"unchecked"})
public Map<String, Object> toMap(Object map) {
@ -59,9 +70,9 @@ public abstract class AbstractJsonProvider implements JsonProvider {
/**
* Extracts a value from a Map
*
* @param map
* @param key
* @return
* @param map map to read from
* @param key key to read
* @return value of key in map
*/
public Object getMapValue(Object map, String key) {
return toMap(map).get(key);

1
json-path/src/main/java/com/jayway/jsonpath/spi/impl/JacksonProvider.java

@ -31,6 +31,7 @@ import java.util.*;
public class JacksonProvider extends AbstractJsonProvider implements MappingProvider{
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public Mode getMode() {
return Mode.STRICT;

4
json-path/src/main/java/com/jayway/jsonpath/spi/impl/JsonSmartJsonProvider.java

@ -83,9 +83,9 @@ public class JsonSmartJsonProvider extends AbstractJsonProvider {
public String toJson(Object obj) {
if(obj instanceof Map) {
return JSONObject.toJSONString((Map<String, ? extends Object>) obj);
return JSONObject.toJSONString((Map<String, ?>) obj);
} else if(obj instanceof List){
return JSONArray.toJSONString((List<? extends Object>) obj);
return JSONArray.toJSONString((List<?>) obj);
} else {
throw new UnsupportedOperationException(obj.getClass().getName() + " can not be converted to JSON");
}

44
json-path/src/test/java/com/jayway/jsonpath/FilterTest.java

@ -11,9 +11,7 @@ import java.util.regex.Pattern;
import static com.jayway.jsonpath.Criteria.where;
import static com.jayway.jsonpath.Filter.filter;
import static java.util.Arrays.asList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.*;
/**
* Created by IntelliJ IDEA.
@ -131,10 +129,10 @@ public class FilterTest {
check.put("foo", 12.5D);
check.put("foo_null", null);
assertTrue(filter(where("foo").lt(13D)).accept(check));
assertFalse(filter(where("foo").lt(null)).accept(check));
assertFalse(filter(where("foo").lt(5D)).accept(check));
assertFalse(filter(where("foo_null").lt(5D)).accept(check));
assertTrue(filter(where("foo").lte(13D)).accept(check));
assertFalse(filter(where("foo").lte(null)).accept(check));
assertFalse(filter(where("foo").lte(5D)).accept(check));
assertFalse(filter(where("foo_null").lte(5D)).accept(check));
}
@Test
@ -267,7 +265,7 @@ public class FilterTest {
}
@Test
public void filters_can_be_extended() throws Exception {
public void filters_can_be_extended_with_new_criteria() throws Exception {
Map<String, Object> check = new HashMap<String, Object>();
check.put("string", "foo");
@ -286,6 +284,36 @@ public class FilterTest {
}
@Test
public void filters_criteria_can_be_refined() throws Exception {
Map<String, Object> check = new HashMap<String, Object>();
check.put("string", "foo");
check.put("string_null", null);
check.put("int", 10);
check.put("long", 1L);
check.put("double", 1.12D);
Filter filter = filter(where("string").is("foo"));
assertTrue(filter.accept(check));
Criteria criteria = where("string").is("not eq");
filter.addCriteria(criteria);
assertFalse(filter.accept(check));
filter = filter(where("string").is("foo").and("string").is("not eq"));
assertFalse(filter.accept(check));
filter = filter(where("string").is("foo").and("string").is("foo"));
assertTrue(filter.accept(check));
}
@Test
public void arrays_of_maps_can_be_filtered() throws Exception {

14
pom.xml

@ -216,6 +216,7 @@
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<optional>true</optional>
<version>1.9.5</version>
</dependency>
@ -243,6 +244,18 @@
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
@ -250,7 +263,6 @@
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Loading…
Cancel
Save