From 41ead5638505e8a028c6dd25d357dd25c7823fd1 Mon Sep 17 00:00:00 2001 From: Jochen Berger Date: Fri, 24 May 2013 13:33:19 +0200 Subject: [PATCH] rework JsonProvider so that the backing object don't have to implement List or Map --- .../main/java/com/jayway/jsonpath/Filter.java | 6 +- .../java/com/jayway/jsonpath/JsonModel.java | 4 +- .../java/com/jayway/jsonpath/JsonPath.java | 2 +- .../internal/filter/ArrayEvalFilter.java | 20 ++-- .../internal/filter/ArrayIndexFilter.java | 28 ++--- .../internal/filter/ArrayQueryFilter.java | 3 +- .../jsonpath/internal/filter/FieldFilter.java | 51 ++++---- .../internal/filter/HasFieldFilter.java | 13 +- .../jsonpath/internal/filter/ScanFilter.java | 23 ++-- .../internal/filter/WildcardFilter.java | 16 ++- .../com/jayway/jsonpath/spi/JsonProvider.java | 65 ++++++---- .../spi/impl/AbstractJsonProvider.java | 111 +++++++++++++----- .../jsonpath/spi/impl/JacksonProvider.java | 2 +- .../spi/impl/JsonSmartJsonProvider.java | 2 +- 14 files changed, 194 insertions(+), 152 deletions(-) diff --git a/json-path/src/main/java/com/jayway/jsonpath/Filter.java b/json-path/src/main/java/com/jayway/jsonpath/Filter.java index 2b81e8b6..717ca532 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/Filter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/Filter.java @@ -50,11 +50,11 @@ public abstract class Filter { * @param jsonProvider the json provider that is used to create the result list * @return the filtered list */ - public List doFilter(List filterItems, JsonProvider jsonProvider) { - List result = jsonProvider.createList();; + public Object doFilter(Iterable filterItems, JsonProvider jsonProvider) { + Object result = jsonProvider.createArray(); for (T filterItem : filterItems) { if (accept(filterItem)) { - result.add(filterItem); + jsonProvider.setProperty(result, jsonProvider.length(result), filterItem); } } return result; diff --git a/json-path/src/main/java/com/jayway/jsonpath/JsonModel.java b/json-path/src/main/java/com/jayway/jsonpath/JsonModel.java index e9971b0a..3e9d4252 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/JsonModel.java +++ b/json-path/src/main/java/com/jayway/jsonpath/JsonModel.java @@ -111,7 +111,7 @@ public class JsonModel { * @return true if root is an array */ public boolean isList() { - return jsonProvider.isList(jsonObject); + return jsonProvider.isArray(jsonObject); } /** @@ -249,7 +249,7 @@ public class JsonModel { * @return array operations for this JsonModel */ public ArrayOps opsForArray() { - isTrue(jsonProvider.isList(jsonObject), "This JsonModel is not a JSON array"); + isTrue(jsonProvider.isArray(jsonObject), "This JsonModel is not a JSON array"); return opsForArray(JSON_PATH_ROOT); } diff --git a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java index c20c779f..6a318500 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java +++ b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java @@ -208,7 +208,7 @@ public class JsonPath { JsonProvider jsonProvider = JsonProviderFactory.createProvider(); - if (!jsonProvider.isMap(jsonObject) && !jsonProvider.isList(jsonObject)) { + if (!jsonProvider.isMap(jsonObject) && !jsonProvider.isArray(jsonObject)) { throw new IllegalArgumentException("Invalid container object"); } LinkedList contextFilters = new LinkedList(filters); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java index eb00d0fd..8e769f89 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java @@ -18,8 +18,7 @@ import com.jayway.jsonpath.InvalidPathException; import com.jayway.jsonpath.internal.filter.eval.ExpressionEvaluator; import com.jayway.jsonpath.spi.JsonProvider; -import java.util.List; -import java.util.Map; +import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -51,17 +50,16 @@ public class ArrayEvalFilter extends PathTokenFilter { @Override public Object filter(Object obj, JsonProvider jsonProvider) { - List src = null; + Iterable src = null; try { - src = jsonProvider.toList(obj); + src = jsonProvider.toIterable(obj); } catch (ClassCastException e){ throw new InvalidPathException("The path fragment '" + this.condition + "' can not be applied to a JSON object only a JSON array.", e); } - List result = jsonProvider.createList(); - + Object result = jsonProvider.createArray(); for (Object item : src) { if (isMatch(item, conditionStatement, jsonProvider)) { - result.add(item); + jsonProvider.setProperty(result, jsonProvider.length(result), item); } } return result; @@ -79,19 +77,19 @@ public class ArrayEvalFilter extends PathTokenFilter { private boolean isMatch(Object check, ConditionStatement conditionStatement, JsonProvider jsonProvider) { if (jsonProvider.isMap(check)) { - Map obj = jsonProvider.toMap(check); + Collection keys = jsonProvider.getPropertyKeys(check); - if (!obj.containsKey(conditionStatement.getField())) { + if (!keys.contains(conditionStatement.getField())) { return false; } - Object propertyValue = obj.get(conditionStatement.getField()); + Object propertyValue = jsonProvider.getProperty(check, conditionStatement.getField()); if (jsonProvider.isContainer(propertyValue)) { return false; } return ExpressionEvaluator.eval(propertyValue, conditionStatement.getOperator(), conditionStatement.getExpected()); - } else if(jsonProvider.isList(check)) { + } else if(jsonProvider.isArray(check)) { return false; } else { return ExpressionEvaluator.eval(check, conditionStatement.getOperator(), conditionStatement.getExpected()); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayIndexFilter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayIndexFilter.java index 45681d7a..4df7057b 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayIndexFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayIndexFilter.java @@ -14,10 +14,8 @@ */ package com.jayway.jsonpath.internal.filter; -import com.jayway.jsonpath.InvalidPathException; import com.jayway.jsonpath.spi.JsonProvider; -import java.util.List; import java.util.regex.Pattern; /** @@ -52,17 +50,16 @@ public class ArrayIndexFilter extends PathTokenFilter { @Override - public Object filter(Object obj,JsonProvider jsonProvider) { + public Object filter(Object obj, JsonProvider jsonProvider) { - List src = jsonProvider.toList(obj); - List result = jsonProvider.createList(); + Object result = jsonProvider.createArray(); if (trimmedCondition.contains(OPERATOR)) { if (trimmedCondition.startsWith(OPERATOR)) { String trimmedCondition = trim(this.trimmedCondition, 1, 0); int get = Integer.parseInt(trimmedCondition); for (int i = 0; i < get; i++) { - result.add(src.get(i)); + jsonProvider.setProperty(result, jsonProvider.length(result), jsonProvider.getProperty(obj, i)); } return result; @@ -73,13 +70,13 @@ public class ArrayIndexFilter extends PathTokenFilter { if(get > 0){ get = get * -1; } - return src.get(src.size() + get); + return jsonProvider.getProperty(obj, jsonProvider.length(obj) + get); } else { - int start = src.size() + get; - int stop = src.size(); + int start = jsonProvider.length(obj) + get; + int stop = jsonProvider.length(obj); for (int i = start; i < stop; i ++){ - result.add(src.get(i)); + jsonProvider.setProperty(result, jsonProvider.length(result), jsonProvider.getProperty(obj, i)); } return result; } @@ -91,23 +88,23 @@ public class ArrayIndexFilter extends PathTokenFilter { int stop = Integer.parseInt(indexes[1]); for (int i = start; i < stop; i ++){ - result.add(src.get(i)); + jsonProvider.setProperty(result, jsonProvider.length(result), jsonProvider.getProperty(obj, i)); } return result; } } else { String[] indexArr = COMMA.split(trimmedCondition); - if(src.isEmpty()){ + if(jsonProvider.length(obj) == 0){ return result; } if (indexArr.length == 1) { - return src.get(Integer.parseInt(indexArr[0])); + return jsonProvider.getProperty(obj, indexArr[0]); } else { for (String idx : indexArr) { - result.add(src.get(Integer.parseInt(idx.trim()))); + jsonProvider.setProperty(result, jsonProvider.length(result), jsonProvider.getProperty(obj, idx.trim())); } return result; } @@ -118,8 +115,7 @@ public class ArrayIndexFilter extends PathTokenFilter { public Object getRef(Object obj, JsonProvider jsonProvider) { if(SINGLE_ARRAY_INDEX_PATTERN.matcher(condition).matches()){ String trimmedCondition = trim(condition, 1, 1); - List src = jsonProvider.toList(obj); - return src.get(Integer.parseInt(trimmedCondition)); + return jsonProvider.getProperty(obj, trimmedCondition); } else { throw new UnsupportedOperationException(); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.java index 35044a45..962e249b 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayQueryFilter.java @@ -18,7 +18,6 @@ import com.jayway.jsonpath.Filter; import com.jayway.jsonpath.spi.JsonProvider; import java.util.LinkedList; -import java.util.List; /** * @author Kalle Stenflo @@ -34,7 +33,7 @@ public class ArrayQueryFilter extends PathTokenFilter { Filter filter = filters.poll(); - return filter.doFilter(jsonProvider.toList(obj), jsonProvider); + return filter.doFilter(jsonProvider.toIterable(obj), jsonProvider); } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FieldFilter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FieldFilter.java index 95dba773..1b77c02d 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FieldFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FieldFilter.java @@ -15,13 +15,11 @@ package com.jayway.jsonpath.internal.filter; import com.jayway.jsonpath.Filter; -import com.jayway.jsonpath.InvalidPathException; import com.jayway.jsonpath.PathNotFoundException; import com.jayway.jsonpath.spi.JsonProvider; +import java.util.Collection; import java.util.LinkedList; -import java.util.List; -import java.util.Map; /** * @author Kalle Stenflo @@ -37,34 +35,35 @@ public class FieldFilter extends PathTokenFilter { @Override public Object filter(Object obj, JsonProvider jsonProvider, LinkedList filters, boolean inArrayContext) { - if (jsonProvider.isList(obj)) { + if (jsonProvider.isArray(obj)) { if (!inArrayContext) { throw new PathNotFoundException("Trying to access the field '" + condition +"' in an array context."); } else { - List result = jsonProvider.createList(); - for (Object current : jsonProvider.toList(obj)) { + Object result = jsonProvider.createArray(); + for (Object current : jsonProvider.toIterable(obj)) { if (jsonProvider.isMap(current)) { - - Map map = jsonProvider.toMap(current); - + Collection keys = jsonProvider.getPropertyKeys(current); + if(split.length == 1){ - if (map.containsKey(condition)) { - Object o = map.get(condition); - if (jsonProvider.isList(o)) { - result.addAll(jsonProvider.toList(o)); + if (keys.contains(condition)) { + Object o = jsonProvider.getProperty(current, condition); + if (jsonProvider.isArray(o)) { + for(Object item : jsonProvider.toIterable(o)){ + jsonProvider.setProperty(result, jsonProvider.length(result), item); + } } else { - result.add(map.get(condition)); + jsonProvider.setProperty(result, jsonProvider.length(result), jsonProvider.getProperty(current, condition)); } } } else { - Map res = jsonProvider.createMap(); + Object res = jsonProvider.createMap(); for (String prop : split) { - if (map.containsKey(prop)) { - res.put(prop, map.get(prop)); + if (keys.contains(prop)) { + jsonProvider.setProperty(res, prop, jsonProvider.getProperty(current, prop)); } } - result.add(res); + jsonProvider.setProperty(result, jsonProvider.length(result), res); } } } @@ -72,18 +71,18 @@ public class FieldFilter extends PathTokenFilter { } } else { - Map map = jsonProvider.toMap(obj); - if(!map.containsKey(condition) && split.length == 1){ + Collection keys = jsonProvider.getPropertyKeys(obj); + if(!keys.contains(condition) && split.length == 1){ throw new PathNotFoundException("Path '" + condition + "' not found in the current context."); } else { if(split.length == 1){ - return map.get(condition); + return jsonProvider.getProperty(obj, condition); } else { - Map res = jsonProvider.createMap(); + Object res = jsonProvider.createMap(); for (String prop : split) { - if(map.containsKey(prop)){ - res.put(prop, map.get(prop)); + if(keys.contains(prop)){ + jsonProvider.setProperty(res, prop, jsonProvider.getProperty(obj, prop)); } } return res; @@ -96,10 +95,10 @@ public class FieldFilter extends PathTokenFilter { public Object filter(Object obj, JsonProvider jsonProvider) { - if (jsonProvider.isList(obj)) { + if (jsonProvider.isArray(obj)) { return obj; } else { - return jsonProvider.getMapValue(obj, condition); + return jsonProvider.getProperty(obj, condition); } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/HasFieldFilter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/HasFieldFilter.java index 7a6b62d9..6375c57d 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/HasFieldFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/HasFieldFilter.java @@ -16,8 +16,7 @@ package com.jayway.jsonpath.internal.filter; import com.jayway.jsonpath.spi.JsonProvider; -import java.util.List; -import java.util.Map; +import java.util.Collection; /** * @author Kalle Stenflo @@ -42,14 +41,14 @@ public class HasFieldFilter extends PathTokenFilter { public Object filter(Object obj, JsonProvider jsonProvider) { //[?(@.isbn)] - List src = jsonProvider.toList(obj); - List result = jsonProvider.createList(); + Iterable src = jsonProvider.toIterable(obj); + Object result = jsonProvider.createArray(); for (Object item : src) { if(jsonProvider.isMap(item)){ - Map map = jsonProvider.toMap(item); - if(map.containsKey(trimmedCondition)){ - result.add(map); + Collection keys = jsonProvider.getPropertyKeys(item); + if(keys.contains(trimmedCondition)){ + jsonProvider.setProperty(result, jsonProvider.length(result), item); } } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ScanFilter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ScanFilter.java index 7f6128ce..af1323ac 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ScanFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ScanFilter.java @@ -17,8 +17,6 @@ package com.jayway.jsonpath.internal.filter; import com.jayway.jsonpath.spi.JsonProvider; -import java.util.List; - /** * @author Kalle Stenflo */ @@ -30,7 +28,7 @@ public class ScanFilter extends PathTokenFilter { @Override public Object filter(Object obj, JsonProvider jsonProvider) { - List result = jsonProvider.createList(); + Object result = jsonProvider.createArray(); scan(obj, result, jsonProvider); return result; @@ -47,22 +45,15 @@ public class ScanFilter extends PathTokenFilter { } - private void scan(Object container, List result, JsonProvider jsonProvider) { + private void scan(Object container, Object result, JsonProvider jsonProvider) { if (jsonProvider.isMap(container)) { - result.add(container); - - for (Object value : jsonProvider.toMap(container).values()) { - if (jsonProvider.isContainer(value)) { - scan(value, result, jsonProvider); - } - } - } else if (jsonProvider.isList(container)) { + jsonProvider.setProperty(result, jsonProvider.length(result), container); + } - for (Object value : jsonProvider.toList(container)) { - if (jsonProvider.isContainer(value)) { - scan(value, result, jsonProvider); - } + for (Object value : jsonProvider.toIterable(container)) { + if (jsonProvider.isContainer(value)) { + scan(value, result, jsonProvider); } } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/WildcardFilter.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/WildcardFilter.java index f5acbaaf..6be0d7af 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/WildcardFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/WildcardFilter.java @@ -16,8 +16,6 @@ package com.jayway.jsonpath.internal.filter; import com.jayway.jsonpath.spi.JsonProvider; -import java.util.List; - /** * @author Kalle Stenflo */ @@ -29,17 +27,17 @@ public class WildcardFilter extends PathTokenFilter { @Override public Object filter(Object obj, JsonProvider jsonProvider) { - List result = jsonProvider.createList(); + Object result = jsonProvider.createArray(); - if (jsonProvider.isList(obj)) { - for (Object current : jsonProvider.toList(obj)) { - for (Object value : jsonProvider.toMap(current).values()) { - result.add(value); + if (jsonProvider.isArray(obj)) { + for (Object current : jsonProvider.toIterable(obj)) { + for (Object value : jsonProvider.toIterable(current)) { + jsonProvider.setProperty(result, jsonProvider.length(result), value); } } } else { - for (Object value : jsonProvider.toMap(obj).values()) { - result.add(value); + for (Object value : jsonProvider.toIterable(obj)) { + jsonProvider.setProperty(result, jsonProvider.length(result), value); } } return result; diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/JsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/JsonProvider.java index 67d008b4..dc4b295e 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/JsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/JsonProvider.java @@ -18,8 +18,7 @@ import com.jayway.jsonpath.InvalidJsonException; import java.io.InputStream; import java.io.Reader; -import java.util.List; -import java.util.Map; +import java.util.Collection; /** * @author Kalle Stenflo @@ -37,60 +36,76 @@ public interface JsonProvider { String toJson(Object obj); - Map createMap(); + Object createMap(); - List createList(); + Iterable createArray(); Object clone(Object model); /** - * checks if object is instanceof java.util.List or java.util.Map + * checks if object is a map or an array * * @param obj object to check - * @return true if List or Map + * @return true if obj is a map or an array */ boolean isContainer(Object obj); /** - * checks if object is instanceof java.util.List + * checks if object is an array * * @param obj object to check - * @return true if List + * @return true if obj is an array */ - boolean isList(Object obj); + boolean isArray(Object obj); /** - * Converts give object to a List + * Get the length of an array or object + * @param obj an array or an object + * @return the number of entries in the array or object + */ + int length(Object obj); + + /** + * Converts given object to an {@link Iterable} * - * @param list - * @return + * @param obj an array or an object + * @return the entries for an array or the values for a map */ - List toList(Object list); - + Iterable toIterable(Object obj); + /** - * Converts given object to a Map + * Returns the keys from the given object or the indexes from an array * - * @param map - * @return + * @param obj an array or an object + * @return the keys for an object or the indexes for an array */ - Map toMap(Object map); + Collection getPropertyKeys(Object obj); /** - * Extracts a value from a Map + * Extracts a value from an object or array * - * @param map - * @param key - * @return + * @param obj an array or an object + * @param key a String key or a numerical index + * @return the entry at the given key, i.e. obj[key] */ - Object getMapValue(Object map, String key); + Object getProperty(Object obj, Object key); + + /** + * Sets a value in an object or array + * + * @param obj an array or an object + * @param key a String key or a numerical index + * @param value the value to set + */ + void setProperty(Object obj, Object key, Object value); /** - * checks if object is instanceof java.util.Map + * checks if object is a map (i.e. no array) * * @param obj object to check - * @return true if Map + * @return true if the object is a map */ boolean isMap(Object obj); diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/impl/AbstractJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/impl/AbstractJsonProvider.java index c0abb31e..10999058 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/impl/AbstractJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/impl/AbstractJsonProvider.java @@ -15,9 +15,12 @@ package com.jayway.jsonpath.spi.impl; import com.jayway.jsonpath.spi.JsonProvider; + import org.apache.commons.lang3.SerializationUtils; import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -32,67 +35,111 @@ public abstract class AbstractJsonProvider implements JsonProvider { } /** - * checks if object is instanceof java.util.List or java.util.Map + * checks if object is a map or an array * * @param obj object to check - * @return true if List or Map + * @return true if obj is a map or an array */ public boolean isContainer(Object obj) { - return (isList(obj) || isMap(obj)); + return (isArray(obj) || isMap(obj)); } /** - * checks if object is instanceof java.util.List + * checks if object is an array * * @param obj object to check - * @return true if List + * @return true if obj is an array */ - public boolean isList(Object obj) { + public boolean isArray(Object obj) { return (obj instanceof List); } /** - * Converts give object to a List + * Extracts a value from an object or array * - * @param list object to convert - * @return object as list + * @param obj an array or an object + * @param key a String key or a numerical index + * @return the entry at the given key, i.e. obj[key] */ - @SuppressWarnings({"unchecked"}) - public List toList(Object list) { - return (List) list; + public Object getProperty(Object obj, Object key) { + if (isMap(obj)) + return ((Map) obj).get(key.toString()); + else{ + int index = key instanceof Integer? (Integer) key : Integer.parseInt(key.toString()); + return ((List) obj).get(index); + } } - - + /** - * Converts given object to a Map + * Sets a value in an object or array * - * @param map object to convert - * @return object as map + * @param obj an array or an object + * @param key a String key or a numerical index + * @param value the value to set */ - @SuppressWarnings({"unchecked"}) - public Map toMap(Object map) { - return (Map) map; + public void setProperty(Object obj, Object key, Object value) { + if (isMap(obj)) + ((Map) obj).put(key.toString(), value); + else{ + int index = key instanceof Integer? (Integer) key : Integer.parseInt(key.toString()); + ((List) obj).add(index, value); + } } + /** - * Extracts a value from a Map + * checks if object is a map (i.e. no array) * - * @param map map to read from - * @param key key to read - * @return value of key in map + * @param obj object to check + * @return true if the object is a map */ - public Object getMapValue(Object map, String key) { - return toMap(map).get(key); + public boolean isMap(Object obj) { + return (obj instanceof Map); } - + /** - * checks if object is instanceof java.util.Map + * Returns the keys from the given object or the indexes from an array * - * @param obj object to check - * @return true if Map + * @param obj an array or an object + * @return the keys for an object or the indexes for an array */ - public boolean isMap(Object obj) { - return (obj instanceof Map); + public Collection getPropertyKeys(Object obj) { + if (isArray(obj)){ + List l = (List) obj; + List keys = new ArrayList(l.size()); + for (int i = 0; i < l.size(); i++){ + keys.add(String.valueOf(i)); + } + return keys; + } + else{ + return ((Map)obj).keySet(); + } + } + + /** + * Get the length of an array or object + * @param obj an array or an object + * @return the number of entries in the array or object + */ + public int length(Object obj) { + if (isArray(obj)){ + return ((List)obj).size(); + } + return getPropertyKeys(obj).size(); + } + + /** + * Converts given object to an {@link Iterable} + * + * @param obj an array or an object + * @return the entries for an array or the values for a map + */ + public Iterable toIterable(Object obj) { + if (isArray(obj)) + return ((Iterable) obj); + else + return ((Map)obj).values(); } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JacksonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JacksonProvider.java index f70aa747..2088ffb7 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JacksonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JacksonProvider.java @@ -85,7 +85,7 @@ public class JacksonProvider extends AbstractJsonProvider implements MappingProv } @Override - public List createList() { + public List createArray() { return new LinkedList(); } diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JsonSmartJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JsonSmartJsonProvider.java index 72cb5cbd..1014e5ff 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JsonSmartJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/impl/JsonSmartJsonProvider.java @@ -52,7 +52,7 @@ public class JsonSmartJsonProvider extends AbstractJsonProvider { return containerFactory.createObjectContainer(); } - public List createList() { + public List createArray() { return containerFactory.createArrayContainer(); }