Browse Source

Added generic type in Filter.

pull/8/merge
Kalle Stenflo 13 years ago
parent
commit
3bb1e00e90
  1. 86
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  2. 83
      json-path/src/main/java/com/jayway/jsonpath/Filter.java
  3. 19
      json-path/src/main/java/com/jayway/jsonpath/IndefinitePathException.java
  4. 19
      json-path/src/main/java/com/jayway/jsonpath/InvalidCriteriaException.java
  5. 19
      json-path/src/main/java/com/jayway/jsonpath/InvalidModelPathException.java
  6. 60
      json-path/src/main/java/com/jayway/jsonpath/JsonModel.java
  7. 7
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  8. 22
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.java
  9. 19
      json-path/src/main/java/com/jayway/jsonpath/spi/JsonProviderFactory.java
  10. 19
      json-path/src/main/java/com/jayway/jsonpath/spi/MappingProvider.java
  11. 19
      json-path/src/main/java/com/jayway/jsonpath/spi/MappingProviderFactory.java
  12. 292
      json-path/src/test/java/com/jayway/jsonpath/FilterTest.java
  13. 2
      json-path/src/test/java/com/jayway/jsonpath/JsonModelTest.java
  14. 35
      json-path/src/test/java/com/jayway/jsonpath/JsonPathFilterTest.java

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

@ -1,16 +1,28 @@
/*
* 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; package com.jayway.jsonpath;
import javax.lang.model.type.NullType;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.apache.commons.lang.Validate.notEmpty;
import static org.apache.commons.lang.Validate.notNull;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/5/12
* Time: 12:08 PM
*/ */
public class Criteria { public class Criteria {
@ -30,12 +42,14 @@ public class Criteria {
public Criteria(String key) { public Criteria(String key) {
notEmpty(key, "key can not be null or empty");
this.criteriaChain = new ArrayList<Criteria>(); this.criteriaChain = new ArrayList<Criteria>();
this.criteriaChain.add(this); this.criteriaChain.add(this);
this.key = key; this.key = key;
} }
protected Criteria(List<Criteria> criteriaChain, String key) { protected Criteria(List<Criteria> criteriaChain, String key) {
notEmpty(key, "key can not be null or empty");
this.criteriaChain = criteriaChain; this.criteriaChain = criteriaChain;
this.criteriaChain.add(this); this.criteriaChain.add(this);
this.key = key; this.key = key;
@ -77,6 +91,10 @@ public class Criteria {
expectedVal = this.criteria.get(key); expectedVal = this.criteria.get(key);
if ("$gt".equals(key)) { if ("$gt".equals(key)) {
if (expectedVal == null || actualVal == null) {
return false;
}
Number expectedNumber = (Number) expectedVal; Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal; Number actualNumber = (Number) actualVal;
@ -84,6 +102,10 @@ public class Criteria {
} else if ("$gte".equals(key)) { } else if ("$gte".equals(key)) {
if (expectedVal == null || actualVal == null) {
return false;
}
Number expectedNumber = (Number) expectedVal; Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal; Number actualNumber = (Number) actualVal;
@ -91,6 +113,10 @@ public class Criteria {
} else if ("$lt".equals(key)) { } else if ("$lt".equals(key)) {
if (expectedVal == null || actualVal == null) {
return false;
}
Number expectedNumber = (Number) expectedVal; Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal; Number actualNumber = (Number) actualVal;
@ -98,12 +124,22 @@ public class Criteria {
} else if ("$lte".equals(key)) { } else if ("$lte".equals(key)) {
if (expectedVal == null || actualVal == null) {
return false;
}
Number expectedNumber = (Number) expectedVal; Number expectedNumber = (Number) expectedVal;
Number actualNumber = (Number) actualVal; Number actualNumber = (Number) actualVal;
return (actualNumber.doubleValue() <= expectedNumber.doubleValue()); return (actualNumber.doubleValue() <= expectedNumber.doubleValue());
} else if ("$ne".equals(key)) { } else if ("$ne".equals(key)) {
if (expectedVal == null && actualVal == null) {
return false;
}
if (expectedVal == null) {
return !(actualVal == null);
}
return !expectedVal.equals(actualVal); return !expectedVal.equals(actualVal);
@ -142,22 +178,33 @@ public class Criteria {
} else if ("$type".equals(key)) { } else if ("$type".equals(key)) {
Class<?> exp = (Class<?>) expectedVal; Class<?> exp = (Class<?>) expectedVal;
Class<?> act = map.containsKey(this.key) ? map.get(this.key).getClass() : NullType.class; Class<?> act = null;
if (map.containsKey(this.key)) {
return act.equals(exp); Object actVal = map.get(this.key);
if (actVal != null) {
act = actVal.getClass();
}
}
if (act == null) {
return false;
} else {
return act.equals(exp);
}
} else if ("$regex".equals(key)) { } else if ("$regex".equals(key)) {
Pattern exp = (Pattern) expectedVal; Pattern exp = (Pattern) expectedVal;
String act = (String) actualVal; String act = (String) actualVal;
if(act == null){
return false;
}
return exp.matcher(act).matches(); return exp.matcher(act).matches();
} else if ("$or".equals(key)) { } else if ("$or".equals(key)) {
System.out.println("auch"); throw new UnsupportedOperationException("Or not supported yet");
} }
@ -167,7 +214,12 @@ public class Criteria {
} }
} }
if (isValue != NOT_SET) { if (isValue != NOT_SET) {
return isValue.equals(map.get(key));
if (isValue == null) {
return (map.get(key) == null);
} else {
return isValue.equals(map.get(key));
}
} else { } else {
} }
@ -212,6 +264,15 @@ public class Criteria {
this.isValue = o; this.isValue = o;
return this; return this;
} }
/**
* Creates a criterion using equality
*
* @param o
* @return
*/
public Criteria eq(Object o) {
return is(o);
}
/** /**
* Creates a criterion using the $ne operator * Creates a criterion using the $ne operator
@ -304,12 +365,12 @@ public class Criteria {
} }
public Criteria nin(Collection<?> o) { public Criteria nin(Collection<?> o) {
notNull(o, "collection can not be null");
criteria.put("$nin", o); criteria.put("$nin", o);
return this; return this;
} }
/** /**
* Creates a criterion using the $all operator * Creates a criterion using the $all operator
* *
@ -430,5 +491,4 @@ public class Criteria {
} }
} }

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

@ -1,23 +1,46 @@
/*
* 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; package com.jayway.jsonpath;
import java.util.*; import java.util.*;
/** /**
* Created by IntelliJ IDEA. * A filter is used to filter the content of a JSON array in a JSONPath.
* User: kallestenflo *
* Date: 3/5/12 * Sample
* Time: 5:31 PM *
* <code>
* String doc = {"items": [{"name" : "john"}, {"name": "bob"}]}
*
* List<String> names = JsonPath.read(doc, "$items[?].name", Filter.filter(Criteria.where("name").is("john"));
* </code>
*
* @See Criteria
*
* @author Kalle Stenflo
*/ */
public abstract class Filter { public abstract class Filter<T> {
public abstract boolean apply(Map<String, Object> map);
public List<?> doFilter(List<Map<String, Object>> filterItems) {
List<Object> result = new ArrayList<Object>();
for (Map<String, Object> filterItem : filterItems) {
if(apply(filterItem)){ public static Filter filter(Criteria criteria) {
return new MapFilter(criteria);
}
public List<T> doFilter(List<T> filterItems) {
List<T> result = new ArrayList<T>();
for (T filterItem : filterItems) {
if (accept(filterItem)) {
result.add(filterItem); result.add(filterItem);
} }
} }
@ -25,9 +48,9 @@ public abstract class Filter {
} }
public static Filter filter(Criteria criteria) { public abstract boolean accept(T obj);
return new MapFilter(criteria);
} public abstract Filter addCriteria(Criteria criteria);
// -------------------------------------------------------- // --------------------------------------------------------
@ -35,7 +58,21 @@ public abstract class Filter {
// Default filter implementation // Default filter implementation
// //
// -------------------------------------------------------- // --------------------------------------------------------
private static class MapFilter extends Filter { public static abstract class FilterAdapter<T> extends Filter<T> {
@Override
public boolean accept(T obj){
return false;
}
@Override
public Filter addCriteria(Criteria criteria) {
throw new UnsupportedOperationException("can not add criteria to a FilterAdapter.");
}
}
private static class MapFilter extends FilterAdapter<Map<String, Object>> {
private HashMap<String, Criteria> criteria = new LinkedHashMap<String, Criteria>(); private HashMap<String, Criteria> criteria = new LinkedHashMap<String, Criteria>();
@ -54,23 +91,17 @@ public abstract class Filter {
return this; return this;
} }
protected List<Criteria> getCriteria() {
return new ArrayList<Criteria>(this.criteria.values());
}
@Override @Override
public boolean apply(Map<String, Object> map) { public boolean accept(Map<String, Object> map) {
for (Criteria criterion : this.criteria.values()) {
for (Criteria criterion : getCriteria()) {
if (!criterion.apply(map)) { if (!criterion.apply(map)) {
return false; return false;
} }
} }
return true; return true;
} }
} }
} }

19
json-path/src/main/java/com/jayway/jsonpath/IndefinitePathException.java

@ -1,10 +1,21 @@
/*
* 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; package com.jayway.jsonpath;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/4/12
* Time: 7:15 PM
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class IndefinitePathException extends RuntimeException { public class IndefinitePathException extends RuntimeException {

19
json-path/src/main/java/com/jayway/jsonpath/InvalidCriteriaException.java

@ -1,10 +1,21 @@
/*
* 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; package com.jayway.jsonpath;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/5/12
* Time: 12:20 PM
*/ */
public class InvalidCriteriaException extends RuntimeException{ public class InvalidCriteriaException extends RuntimeException{
public InvalidCriteriaException() { public InvalidCriteriaException() {

19
json-path/src/main/java/com/jayway/jsonpath/InvalidModelPathException.java

@ -1,10 +1,21 @@
/*
* 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; package com.jayway.jsonpath;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/4/12
* Time: 2:38 PM
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class InvalidModelPathException extends RuntimeException { public class InvalidModelPathException extends RuntimeException {

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

@ -38,6 +38,7 @@ import static org.apache.commons.lang.Validate.notNull;
public class JsonModel { public class JsonModel {
private Object jsonObject; private Object jsonObject;
private JsonProvider jsonProvider;
// -------------------------------------------------------- // --------------------------------------------------------
// //
@ -45,13 +46,11 @@ public class JsonModel {
// //
// -------------------------------------------------------- // --------------------------------------------------------
/** private JsonModel(String jsonObject, JsonProvider jsonProvider) {
* Creates a new JsonModel notNull(jsonObject, "json can not be null");
*
* @param json json string this.jsonProvider = jsonProvider;
*/ this.jsonObject = jsonProvider.parse(jsonObject);
public JsonModel(String json) {
this(JsonProviderFactory.getInstance().parse(json));
} }
/** /**
@ -60,13 +59,13 @@ public class JsonModel {
* *
* @param jsonObject the json object * @param jsonObject the json object
*/ */
private JsonModel(Object jsonObject) { private JsonModel(Object jsonObject, JsonProvider jsonProvider) {
notNull(jsonObject, "json can not be null"); notNull(jsonObject, "json can not be null");
if (!(jsonObject instanceof Map) && !(jsonObject instanceof List)) { if (!(jsonObject instanceof Map) && !(jsonObject instanceof List)) {
throw new IllegalArgumentException("Invalid container object"); throw new IllegalArgumentException("Invalid container object");
} }
this.jsonProvider = jsonProvider;
this.jsonObject = jsonObject; this.jsonObject = jsonObject;
} }
@ -75,10 +74,10 @@ public class JsonModel {
* *
* @param jsonInputStream the input stream * @param jsonInputStream the input stream
*/ */
private JsonModel(InputStream jsonInputStream) { private JsonModel(InputStream jsonInputStream, JsonProvider jsonProvider) {
notNull(jsonInputStream, "jsonInputStream can not be null"); notNull(jsonInputStream, "jsonInputStream can not be null");
this.jsonProvider = jsonProvider;
this.jsonObject = JsonProviderFactory.getInstance().parse(jsonInputStream); this.jsonObject = jsonProvider.parse(jsonInputStream);
} }
/** /**
@ -87,13 +86,14 @@ public class JsonModel {
* @param jsonURL the URL to read * @param jsonURL the URL to read
* @throws IOException * @throws IOException
*/ */
private JsonModel(URL jsonURL) throws IOException { private JsonModel(URL jsonURL, JsonProvider jsonProvider) throws IOException {
notNull(jsonURL, "jsonURL can not be null"); notNull(jsonURL, "jsonURL can not be null");
InputStream jsonInputStream = null; InputStream jsonInputStream = null;
try { try {
jsonInputStream = jsonURL.openStream(); jsonInputStream = jsonURL.openStream();
this.jsonObject = JsonProviderFactory.getInstance().parse(jsonInputStream); this.jsonObject = jsonProvider.parse(jsonInputStream);
this.jsonProvider = jsonProvider;
} finally { } finally {
IOUtils.closeQuietly(jsonInputStream); IOUtils.closeQuietly(jsonInputStream);
} }
@ -160,18 +160,18 @@ public class JsonModel {
// JSON extractors // JSON extractors
// //
// -------------------------------------------------------- // --------------------------------------------------------
public String toJson() { public String getJson() {
return JsonProviderFactory.getInstance().toJson(jsonObject); return jsonProvider.toJson(jsonObject);
} }
public String toJson(String jsonPath) { public String getJson(String jsonPath, Filter... filters) {
return toJson(JsonPath.compile(jsonPath)); return getJson(JsonPath.compile(jsonPath, filters));
} }
public String toJson(JsonPath jsonPath) { public String getJson(JsonPath jsonPath) {
notNull(jsonPath, "jsonPath can not be null"); notNull(jsonPath, "jsonPath can not be null");
return JsonProviderFactory.getInstance().toJson(get(jsonPath)); return jsonProvider.toJson(get(jsonPath));
} }
// -------------------------------------------------------- // --------------------------------------------------------
@ -180,8 +180,8 @@ public class JsonModel {
// //
// -------------------------------------------------------- // --------------------------------------------------------
public JsonModel getModel(String jsonPath) { public JsonModel getModel(String jsonPath, Filter... filters) {
return getModel(JsonPath.compile(jsonPath)); return getModel(JsonPath.compile(jsonPath, filters));
} }
public JsonModel getModel(JsonPath jsonPath) { public JsonModel getModel(JsonPath jsonPath) {
@ -193,7 +193,7 @@ public class JsonModel {
throw new InvalidModelPathException("The path " + jsonPath.getPath() + " returned an invalid model " + (subModel != null ? subModel.getClass() : "null")); throw new InvalidModelPathException("The path " + jsonPath.getPath() + " returned an invalid model " + (subModel != null ? subModel.getClass() : "null"));
} }
return new JsonModel(subModel); return new JsonModel(subModel, this.jsonProvider);
} }
// -------------------------------------------------------- // --------------------------------------------------------
@ -205,7 +205,7 @@ public class JsonModel {
return map(JsonPath.compile(jsonPath)); return map(JsonPath.compile(jsonPath));
} }
public MappingModelReader map(final JsonPath jsonPath) { public MappingModelReader map(JsonPath jsonPath) {
notNull(jsonPath, "jsonPath can not be null"); notNull(jsonPath, "jsonPath can not be null");
return new DefaultMappingModelReader(JsonModel.this.get(jsonPath)); return new DefaultMappingModelReader(JsonModel.this.get(jsonPath));
@ -219,25 +219,25 @@ public class JsonModel {
public static JsonModel create(String json) { public static JsonModel create(String json) {
notEmpty(json, "json can not be null or empty"); notEmpty(json, "json can not be null or empty");
return new JsonModel(json); return new JsonModel(json, JsonProviderFactory.getInstance());
} }
public static JsonModel create(Object jsonObject) { public static JsonModel create(Object jsonObject) {
notNull(jsonObject, "jsonObject can not be null"); notNull(jsonObject, "jsonObject can not be null");
return new JsonModel(jsonObject); return new JsonModel(jsonObject, JsonProviderFactory.getInstance());
} }
public static JsonModel create(URL url) throws IOException { public static JsonModel create(URL url) throws IOException {
notNull(url, "url can not be null"); notNull(url, "url can not be null");
return new JsonModel(url); return new JsonModel(url, JsonProviderFactory.getInstance());
} }
public static JsonModel create(InputStream jsonInputStream) throws IOException { public static JsonModel create(InputStream jsonInputStream) throws IOException {
notNull(jsonInputStream, "jsonInputStream can not be null"); notNull(jsonInputStream, "jsonInputStream can not be null");
return new JsonModel(jsonInputStream); return new JsonModel(jsonInputStream, JsonProviderFactory.getInstance());
} }
// -------------------------------------------------------- // --------------------------------------------------------
@ -456,9 +456,5 @@ public class JsonModel {
public <T> T to(Class<T> targetClass) { public <T> T to(Class<T> targetClass) {
return MappingProviderFactory.getInstance().convertValue(model, targetClass); return MappingProviderFactory.getInstance().convertValue(model, targetClass);
} }
} }
} }

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

@ -97,16 +97,9 @@ public class JsonPath {
private static Pattern DEFINITE_PATH_PATTERN = Pattern.compile(".*(\\.\\.|\\*|\\[[\\\\/]|\\?|,|:\\s?\\]|\\[\\s?:|>|\\(|<|=|\\+).*"); private static Pattern DEFINITE_PATH_PATTERN = Pattern.compile(".*(\\.\\.|\\*|\\[[\\\\/]|\\?|,|:\\s?\\]|\\[\\s?:|>|\\(|<|=|\\+).*");
private static final Filter[] NO_FILTERS = new Filter[0];
private PathTokenizer tokenizer; private PathTokenizer tokenizer;
private LinkedList<Filter> filters; private LinkedList<Filter> filters;
private JsonPath(String jsonPath) {
this(jsonPath, new Filter[0]);
}
public JsonPath(String jsonPath, Filter[] filters) { public JsonPath(String jsonPath, Filter[] filters) {
if (jsonPath == null || if (jsonPath == null ||
jsonPath.trim().isEmpty() || jsonPath.trim().isEmpty() ||

22
json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.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.internal.filter; package com.jayway.jsonpath.internal.filter;
import com.jayway.jsonpath.Filter; import com.jayway.jsonpath.Filter;
@ -8,10 +22,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/5/12
* Time: 4:41 PM
*/ */
public class ArrayQueryFilter extends PathTokenFilter { public class ArrayQueryFilter extends PathTokenFilter {
@ -24,7 +35,8 @@ public class ArrayQueryFilter extends PathTokenFilter {
Filter filter = filters.poll(); Filter filter = filters.poll();
return filter.doFilter((List<Map<String, Object>>) obj); return filter.doFilter((List)obj);
} }
@Override @Override

19
json-path/src/main/java/com/jayway/jsonpath/spi/JsonProviderFactory.java

@ -1,12 +1,23 @@
/*
* 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; package com.jayway.jsonpath.spi;
import com.jayway.jsonpath.spi.impl.JsonSmartJsonProvider; import com.jayway.jsonpath.spi.impl.JsonSmartJsonProvider;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/2/12
* Time: 9:45 PM
*/ */
public abstract class JsonProviderFactory { public abstract class JsonProviderFactory {

19
json-path/src/main/java/com/jayway/jsonpath/spi/MappingProvider.java

@ -1,12 +1,23 @@
/*
* 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; package com.jayway.jsonpath.spi;
import java.util.Collection; import java.util.Collection;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/5/12
* Time: 11:03 AM
*/ */
public interface MappingProvider { public interface MappingProvider {

19
json-path/src/main/java/com/jayway/jsonpath/spi/MappingProviderFactory.java

@ -1,12 +1,23 @@
/*
* 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; package com.jayway.jsonpath.spi;
import com.jayway.jsonpath.spi.impl.JacksonProvider; import com.jayway.jsonpath.spi.impl.JacksonProvider;
/** /**
* Created by IntelliJ IDEA. * @author Kalle Stenflo
* User: kallestenflo
* Date: 3/5/12
* Time: 11:03 AM
*/ */
public class MappingProviderFactory { public class MappingProviderFactory {

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

@ -2,13 +2,16 @@ package com.jayway.jsonpath;
import org.junit.Test; import org.junit.Test;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static com.jayway.jsonpath.Criteria.where; import static com.jayway.jsonpath.Criteria.where;
import static com.jayway.jsonpath.Filter.filter; import static com.jayway.jsonpath.Filter.filter;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.assertTrue;
@ -56,29 +59,115 @@ public class FilterTest {
"}"; "}";
//-------------------------------------------------
//
// Single filter tests
//
//-------------------------------------------------
@Test @Test
public void a_single_is_filter_can_be_built_and_applied() throws Exception { public void is_filters_evaluates() throws Exception {
Map<String, Object> check = JsonPath.read(DOCUMENT, "store.book[0]"); Map<String, Object> check = new HashMap<String, Object>();
Filter filter = Filter.filter(Criteria.where("category").is("reference")); check.put("foo", "foo");
assertTrue(filter.apply(check)); check.put("bar", null);
assertTrue(filter(where("bar").is(null)).accept(check));
assertTrue(filter(where("foo").is("foo")).accept(check));
assertFalse(filter(where("foo").is("xxx")).accept(check));
assertFalse(filter(where("bar").is("xxx")).accept(check));
} }
@Test @Test
public void multiple_filters_can_be_built_and_applied() throws Exception { public void ne_filters_evaluates() throws Exception {
Map<String, Object> check = JsonPath.read(DOCUMENT, "store.book[0]"); Map<String, Object> check = new HashMap<String, Object>();
check.put("foo", "foo");
Filter filter = Filter.filter(Criteria check.put("bar", null);
.where("category").is("reference")
.and("author").is("Nigel Rees") assertTrue(filter(where("foo").ne(null)).accept(check));
.and("price").gt(8) assertTrue(filter(where("foo").ne("not foo")).accept(check));
.and("price").gte(8) assertFalse(filter(where("foo").ne("foo")).accept(check));
.and("price").lt(10) assertFalse(filter(where("bar").ne(null)).accept(check));
.and("price").lte(10) }
.and("title").ne("is not")
.and("title").in("is not", "Sayings of the Century") @Test
.and("title").nin("is not this", "is not that") public void gt_filters_evaluates() throws Exception {
); Map<String, Object> check = new HashMap<String, Object>();
assertTrue(filter.apply(check)); check.put("foo", 12.5D);
check.put("foo_null", null);
assertTrue(filter(where("foo").gt(12D)).accept(check));
assertFalse(filter(where("foo").gt(null)).accept(check));
assertFalse(filter(where("foo").gt(20D)).accept(check));
assertFalse(filter(where("foo_null").gt(20D)).accept(check));
}
@Test
public void gte_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>();
check.put("foo", 12.5D);
check.put("foo_null", null);
assertTrue(filter(where("foo").gte(12D)).accept(check));
assertTrue(filter(where("foo").gte(12.5D)).accept(check));
assertFalse(filter(where("foo").gte(null)).accept(check));
assertFalse(filter(where("foo").gte(20D)).accept(check));
assertFalse(filter(where("foo_null").gte(20D)).accept(check));
}
@Test
public void lt_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>();
check.put("foo", 10.5D);
check.put("foo_null", null);
assertTrue(filter(where("foo").lt(12D)).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));
}
@Test
public void lte_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>();
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));
}
@Test
public void in_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>();
check.put("item", 3);
check.put("null_item", null);
assertTrue(filter(where("item").in(1, 2, 3)).accept(check));
assertTrue(filter(where("item").in(asList(1, 2, 3))).accept(check));
assertFalse(filter(where("item").in(4, 5, 6)).accept(check));
assertFalse(filter(where("item").in(asList(4, 5, 6))).accept(check));
assertFalse(filter(where("item").in(asList('A'))).accept(check));
assertFalse(filter(where("item").in(asList((Object) null))).accept(check));
assertTrue(filter(where("null_item").in((Object) null)).accept(check));
assertFalse(filter(where("null_item").in(1, 2, 3)).accept(check));
}
@Test
public void nin_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>();
check.put("item", 3);
check.put("null_item", null);
assertTrue(filter(where("item").nin(4, 5)).accept(check));
assertTrue(filter(where("item").nin(asList(4, 5))).accept(check));
assertTrue(filter(where("item").nin(asList('A'))).accept(check));
assertTrue(filter(where("null_item").nin(1, 2, 3)).accept(check));
assertTrue(filter(where("item").nin(asList((Object) null))).accept(check));
assertFalse(filter(where("item").nin(3)).accept(check));
assertFalse(filter(where("item").nin(asList(3))).accept(check));
} }
@Test @Test
@ -86,77 +175,184 @@ public class FilterTest {
Map<String, Object> check = new HashMap<String, Object>(); Map<String, Object> check = new HashMap<String, Object>();
check.put("items", asList(1, 2, 3)); check.put("items", asList(1, 2, 3));
assertTrue(filter(where("items").all(1, 2, 3)).accept(check));
assertTrue(filter(where("items").all(1, 2, 3)).apply(check)); assertFalse(filter(where("items").all(1, 2, 3, 4)).accept(check));
assertFalse(filter(where("items").all(1, 2, 3, 4)).apply(check));
} }
@Test @Test
public void size_filters_evaluates() throws Exception { public void size_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>(); Map<String, Object> check = new HashMap<String, Object>();
check.put("items", asList(1, 2, 3)); check.put("items", asList(1, 2, 3));
check.put("items_empty", Collections.emptyList());
assertTrue(filter(where("items").size(3)).accept(check));
assertTrue(filter(where("items").size(3)).apply(check)); assertTrue(filter(where("items_empty").size(0)).accept(check));
assertFalse(filter(where("items").size(2)).apply(check)); assertFalse(filter(where("items").size(2)).accept(check));
} }
@Test @Test
public void exists_filters_evaluates() throws Exception { public void exists_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>(); Map<String, Object> check = new HashMap<String, Object>();
check.put("foo", "foo"); check.put("foo", "foo");
check.put("foo_null", null);
assertTrue(filter(where("foo").exists(true)).accept(check));
assertFalse(filter(where("foo").exists(false)).accept(check));
assertTrue(filter(where("foo").exists(true)).apply(check)); assertTrue(filter(where("foo_null").exists(true)).accept(check));
assertFalse(filter(where("foo").exists(false)).apply(check)); assertFalse(filter(where("foo_null").exists(false)).accept(check));
assertTrue(filter(where("bar").exists(false)).apply(check)); assertTrue(filter(where("bar").exists(false)).accept(check));
assertFalse(filter(where("bar").exists(true)).apply(check)); assertFalse(filter(where("bar").exists(true)).accept(check));
} }
@Test @Test
public void type_filters_evaluates() throws Exception { public void type_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>(); Map<String, Object> check = new HashMap<String, Object>();
check.put("string", "foo"); check.put("string", "foo");
check.put("string_null", null);
check.put("int", 1); check.put("int", 1);
check.put("long", 1L); check.put("long", 1L);
check.put("double", 1.12D); check.put("double", 1.12D);
assertFalse(filter(where("string_null").type(String.class)).accept(check));
assertTrue(filter(where("string").type(String.class)).accept(check));
assertFalse(filter(where("string").type(Number.class)).accept(check));
assertTrue(filter(where("string").type(String.class)).apply(check)); assertTrue(filter(where("int").type(Integer.class)).accept(check));
assertFalse(filter(where("string").type(Number.class)).apply(check)); assertFalse(filter(where("int").type(Long.class)).accept(check));
assertTrue(filter(where("int").type(Integer.class)).apply(check));
assertFalse(filter(where("int").type(Long.class)).apply(check));
assertTrue(filter(where("long").type(Long.class)).apply(check)); assertTrue(filter(where("long").type(Long.class)).accept(check));
assertFalse(filter(where("long").type(Integer.class)).apply(check)); assertFalse(filter(where("long").type(Integer.class)).accept(check));
assertTrue(filter(where("double").type(Double.class)).apply(check)); assertTrue(filter(where("double").type(Double.class)).accept(check));
assertFalse(filter(where("double").type(Integer.class)).apply(check)); assertFalse(filter(where("double").type(Integer.class)).accept(check));
} }
@Test @Test
public void pattern_filters_evaluates() throws Exception { public void pattern_filters_evaluates() throws Exception {
Map<String, Object> check = new HashMap<String, Object>(); Map<String, Object> check = new HashMap<String, Object>();
check.put("string", "kalle"); check.put("name", "kalle");
check.put("name_null", null);
assertTrue(filter(where("string").regex(Pattern.compile(".alle"))).apply(check)); assertFalse(filter(where("name_null").regex(Pattern.compile(".alle"))).accept(check));
assertFalse(filter(where("string").regex(Pattern.compile("KALLE"))).apply(check)); assertTrue(filter(where("name").regex(Pattern.compile(".alle"))).accept(check));
assertTrue(filter(where("string").regex(Pattern.compile("KALLE", Pattern.CASE_INSENSITIVE))).apply(check)); assertFalse(filter(where("name").regex(Pattern.compile("KALLE"))).accept(check));
assertTrue(filter(where("name").regex(Pattern.compile("KALLE", Pattern.CASE_INSENSITIVE))).accept(check));
} }
/* //-------------------------------------------------
//
// Single filter tests
//
//-------------------------------------------------
@Test @Test
public void or_filters_evaluates() throws Exception { public void filters_can_be_combined() throws Exception {
Map<String, Object> check = new HashMap<String, Object>(); Map<String, Object> check = new HashMap<String, Object>();
check.put("string", "kalle"); check.put("string", "foo");
check.put("string_null", null);
check.put("int", 10);
check.put("long", 1L);
check.put("double", 1.12D);
Filter shouldMarch = filter(where("string").is("foo").and("int").lt(11));
assertTrue(filter(where("string").is("x").orOperator(where("string").is("kalle"))).apply(check)); Filter shouldNotMarch = filter(where("string").is("foo").and("int").gt(11));
}*/
assertTrue(shouldMarch.accept(check));
assertFalse(shouldNotMarch.accept(check));
}
@Test
public void filters_can_be_extended() 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").and("int").lt(11));
assertTrue(filter.accept(check));
filter.addCriteria(where("long").ne(1L));
assertFalse(filter.accept(check));
}
@Test
public void arrays_of_maps_can_be_filtered() throws Exception {
Map<String, Object> rootGrandChild_A = new HashMap<String, Object>();
rootGrandChild_A.put("name", "rootGrandChild_A");
Map<String, Object> rootGrandChild_B = new HashMap<String, Object>();
rootGrandChild_B.put("name", "rootGrandChild_B");
Map<String, Object> rootGrandChild_C = new HashMap<String, Object>();
rootGrandChild_C.put("name", "rootGrandChild_C");
Map<String, Object> rootChild_A = new HashMap<String, Object>();
rootChild_A.put("name", "rootChild_A");
rootChild_A.put("children", asList(rootGrandChild_A, rootGrandChild_B, rootGrandChild_C));
Map<String, Object> rootChild_B = new HashMap<String, Object>();
rootChild_B.put("name", "rootChild_B");
rootChild_B.put("children", asList(rootGrandChild_A, rootGrandChild_B, rootGrandChild_C));
Map<String, Object> rootChild_C = new HashMap<String, Object>();
rootChild_C.put("name", "rootChild_C");
rootChild_C.put("children", asList(rootGrandChild_A, rootGrandChild_B, rootGrandChild_C));
Map<String, Object> root = new HashMap<String, Object>();
root.put("children", asList(rootChild_A, rootChild_B, rootChild_C));
Filter customFilter = new Filter.FilterAdapter<Map<String, Object>>() {
@Override
public boolean accept(Map<String, Object> map) {
if(map.get("name").equals("rootGrandChild_A")){
return true;
}
return false;
}
};
Filter rootChildFilter = filter(where("name").regex(Pattern.compile("rootChild_[A|B]")));
Filter rootGrandChildFilter = filter(where("name").regex(Pattern.compile("rootGrandChild_[A|B]")));
List read = JsonPath.read(root, "children[?].children[?][?]", rootChildFilter, rootGrandChildFilter, customFilter);
System.out.println(read.size());
}
@Test
public void arrays_of_objects_can_be_filtered() throws Exception {
Map<String, Object> doc = new HashMap<String, Object>();
doc.put("items", asList(1, 2, 3));
Filter customFilter = new Filter.FilterAdapter(){
@Override
public boolean accept(Object o) {
return 1 == (Integer)o;
}
};
List<Integer> res = JsonPath.read(doc, "$.items[?]", customFilter);
assertEquals(1, res.get(0).intValue());
}
} }

2
json-path/src/test/java/com/jayway/jsonpath/JsonModelTest.java

@ -83,7 +83,7 @@ public class JsonModelTest {
assertEquals("value", model.get("$child.key")); assertEquals("value", model.get("$child.key"));
assertEquals(1, model.get("$items[1]")); assertEquals(1, model.get("$items[1]"));
assertEquals("{\"child\":{\"key\":\"value\"},\"items\":[0,1,2]}", model.toJson()); assertEquals("{\"child\":{\"key\":\"value\"},\"items\":[0,1,2]}", model.getJson());
} }

35
json-path/src/test/java/com/jayway/jsonpath/JsonPathFilterTest.java

@ -10,6 +10,7 @@ import java.util.regex.Pattern;
import static com.jayway.jsonpath.Criteria.where; import static com.jayway.jsonpath.Criteria.where;
import static com.jayway.jsonpath.Filter.filter; import static com.jayway.jsonpath.Filter.filter;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static junit.framework.Assert.assertEquals;
/** /**
* Created by IntelliJ IDEA. * Created by IntelliJ IDEA.
@ -53,20 +54,11 @@ public class JsonPathFilterTest {
" }\n" + " }\n" +
" }\n" + " }\n" +
"}"; "}";
@Test
public void a_path_can_use_filters() throws Exception {
Filter lowPricedBooksFilter = filter(where("price").lt(10));
List read = JsonPath.read(DOCUMENT, "store.book[?]", lowPricedBooksFilter);
System.out.println(read.size());
}
@Test @Test
public void a_path_can_use_many_filters() throws Exception { public void arrays_of_maps_can_be_filtered() throws Exception {
Map<String, Object> rootGrandChild_A = new HashMap<String, Object>(); Map<String, Object> rootGrandChild_A = new HashMap<String, Object>();
@ -96,9 +88,9 @@ public class JsonPathFilterTest {
Filter customFilter = new Filter() { Filter customFilter = new Filter.FilterAdapter<Map<String, Object>>() {
@Override @Override
public boolean apply(Map<String, Object> map) { public boolean accept(Map<String, Object> map) {
if(map.get("name").equals("rootGrandChild_A")){ if(map.get("name").equals("rootGrandChild_A")){
return true; return true;
} }
@ -111,7 +103,26 @@ public class JsonPathFilterTest {
List read = JsonPath.read(root, "children[?].children[?][?]", rootChildFilter, rootGrandChildFilter, customFilter); List read = JsonPath.read(root, "children[?].children[?][?]", rootChildFilter, rootGrandChildFilter, customFilter);
System.out.println(read.size()); System.out.println(read.size());
} }
@Test
public void arrays_of_objects_can_be_filtered() throws Exception {
Map<String, Object> doc = new HashMap<String, Object>();
doc.put("items", asList(1, 2, 3));
Filter customFilter = new Filter.FilterAdapter<Integer>(){
@Override
public boolean accept(Integer o) {
return 1 == o;
}
};
List<Integer> res = JsonPath.read(doc, "$.items[?]", customFilter);
assertEquals(1, res.get(0).intValue());
}
} }

Loading…
Cancel
Save