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 b46af94e..47c4a9f5 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java +++ b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java @@ -178,7 +178,7 @@ public class JsonPath { Object res = path.evaluate(jsonObject, jsonObject, configuration).getValue(false); if(optAlwaysReturnList && path.isDefinite()){ Object array = configuration.jsonProvider().createArray(); - configuration.jsonProvider().setProperty(array, 0, res); + configuration.jsonProvider().setArrayIndex(array, 0, res); return (T)array; } else { return (T)res; diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java b/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java index c7fff03a..391fb8a1 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java @@ -89,7 +89,7 @@ public abstract class PathRef implements Comparable { @Override public void add(Object newVal, Configuration configuration) { if(configuration.jsonProvider().isArray(parent)){ - configuration.jsonProvider().setProperty(parent, null, newVal); + configuration.jsonProvider().setArrayIndex(parent, configuration.jsonProvider().length(parent), newVal); } else { throw new InvalidModificationException("Invalid add operation. $ is not an array"); } @@ -185,7 +185,7 @@ public abstract class PathRef implements Comparable { return; } if(configuration.jsonProvider().isArray(target)){ - configuration.jsonProvider().setProperty(target, null, value); + configuration.jsonProvider().setArrayIndex(target, configuration.jsonProvider().length(target), value); } else { throw new InvalidModificationException("Can only add to an array"); } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/token/EvaluationContextImpl.java b/json-path/src/main/java/com/jayway/jsonpath/internal/token/EvaluationContextImpl.java index c85419a9..b2a1ecef 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/token/EvaluationContextImpl.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/token/EvaluationContextImpl.java @@ -80,8 +80,8 @@ public class EvaluationContextImpl implements EvaluationContext { updateOperations.add(operation); } - configuration.jsonProvider().setProperty(valueResult, resultIndex, model); - configuration.jsonProvider().setProperty(pathResult, resultIndex, path); + configuration.jsonProvider().setArrayIndex(valueResult, resultIndex, model); + configuration.jsonProvider().setArrayIndex(pathResult, resultIndex, path); resultIndex++; if(!configuration().getEvaluationListeners().isEmpty()){ int idx = resultIndex - 1; diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/AbstractJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/AbstractJsonProvider.java index 0a7d7275..51cd39de 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/AbstractJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/AbstractJsonProvider.java @@ -56,7 +56,12 @@ public abstract class AbstractJsonProvider implements JsonProvider { if (!isArray(array)) { throw new UnsupportedOperationException(); } else { - ((List) array).set(index, newValue); + List l = (List) array; + if (index == l.size()){ + l.add(newValue); + }else { + l.set(index, newValue); + } } } @@ -78,10 +83,10 @@ public abstract class AbstractJsonProvider implements JsonProvider { } /** - * Sets a value in an object or array + * Sets a value in an object * - * @param obj an array or an object - * @param key a String key or a numerical index + * @param obj an object + * @param key a String key * @param value the value to set */ @SuppressWarnings("unchecked") @@ -89,14 +94,7 @@ public abstract class AbstractJsonProvider implements JsonProvider { if (isMap(obj)) ((Map) obj).put(key.toString(), value); else { - List list = (List) obj; - int index; - if (key != null) { - index = key instanceof Integer ? (Integer) key : Integer.parseInt(key.toString()); - } else { - index = list.size(); - } - list.add(index, value); + throw new JsonPathException("setProperty operation cannot be used with " + obj!=null?obj.getClass().getName():"null"); } } @@ -159,21 +157,21 @@ public abstract class AbstractJsonProvider implements JsonProvider { } else if(obj instanceof String){ return ((String)obj).length(); } - throw new JsonPathException("length operation can not applied to " + obj!=null?obj.getClass().getName():"null"); + throw new JsonPathException("length operation cannot be applied to " + obj!=null?obj.getClass().getName():"null"); } /** - * Converts given object to an {@link Iterable} + * Converts given array to an {@link Iterable} * - * @param obj an array or an object - * @return the entries for an array or the values for a map + * @param obj an array + * @return an Iterable that iterates over the entries of an array */ @SuppressWarnings("unchecked") public Iterable toIterable(Object obj) { if (isArray(obj)) return ((Iterable) obj); else - return ((Map) obj).values(); + throw new JsonPathException("Cannot iterate over " + obj!=null?obj.getClass().getName():"null"); } @Override diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java index 95bf35b5..d14fdda9 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java @@ -134,10 +134,11 @@ public class GsonJsonProvider extends AbstractJsonProvider { @Override public void setArrayIndex(Object array, int index, Object newValue) { - if (!isArray(array)) { - throw new UnsupportedOperationException(); + JsonArray a = toJsonArray(array); + if (index == a.size()) { + a.add(createJsonElement(newValue)); } else { - toJsonArray(array).set (index, createJsonElement(newValue)); + a.set(index, createJsonElement(newValue)); } } @@ -219,21 +220,12 @@ public class GsonJsonProvider extends AbstractJsonProvider { @Override public Iterable toIterable(Object obj) { - if (isArray(obj)) { - JsonArray arr = toJsonArray(obj); - List values = new ArrayList(arr.size()); - for (Object o : arr) { - values.add(unwrap(o)); - } - return values; - } else { - JsonObject jsonObject = toJsonObject(obj); - List values = new ArrayList(); - for (Map.Entry entry : jsonObject.entrySet()) { - values.add(unwrap(entry.getValue())); - } - return values; + JsonArray arr = toJsonArray(obj); + List values = new ArrayList(arr.size()); + for (Object o : arr) { + values.add(unwrap(o)); } + return values; } private JsonElement createJsonElement(Object o) { diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java index 8ef4cd18..0ad06527 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java @@ -217,21 +217,12 @@ public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider { @Override public Iterable toIterable(Object obj) { - if (isArray(obj)) { - ArrayNode arr = toJsonArray(obj); - List values = new ArrayList(arr.size()); - for (Object o : arr) { - values.add(unwrap(o)); - } - return values; - } else { - List values = new ArrayList(); - Iterator iter = toJsonObject(obj).elements(); - while (iter.hasNext()){ - values.add(unwrap(iter.next())); - } - return values; + ArrayNode arr = toJsonArray(obj); + List values = new ArrayList(arr.size()); + for (Object o : arr) { + values.add(unwrap(o)); } + return values; } private JsonNode createJsonElement(Object o) { diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java index 3432a416..92f63ccd 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java @@ -76,10 +76,10 @@ public interface JsonProvider { int length(Object obj); /** - * Converts given object to an {@link Iterable} + * Converts given array to an {@link Iterable} * - * @param obj an array or an object - * @return the entries for an array or the values for a map + * @param obj an array + * @return an Iterable that iterates over the entries of an array */ Iterable toIterable(Object obj); @@ -113,7 +113,7 @@ public interface JsonProvider { Object getArrayIndex(Object obj, int idx, boolean unwrap); /** - * Sets a value in an array + * Sets a value in an array. If the array is too small, the provider is supposed to enlarge it. * * @param array an array * @param idx index @@ -131,10 +131,10 @@ public interface JsonProvider { Object getMapValue(Object obj, String key); /** - * Sets a value in an object or array + * Sets a value in an object * - * @param obj an array or an object - * @param key a String key or a numerical index + * @param obj an object + * @param key a String key * @param value the value to set */ void setProperty(Object obj, Object key, Object value);