diff options
author | Narayan Kamath <narayan@google.com> | 2014-01-10 10:57:33 +0000 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2014-01-13 10:46:06 +0000 |
commit | 2ea1d56a1f70aeb0441209cda10756a301474bf4 (patch) | |
tree | e8f15bb12ad6a943baa55da8c867198228fcb893 /json/src | |
parent | b5db5ba4718919c37538fc57cb451c049b8ba8a3 (diff) | |
download | libcore-2ea1d56a1f70aeb0441209cda10756a301474bf4.zip libcore-2ea1d56a1f70aeb0441209cda10756a301474bf4.tar.gz libcore-2ea1d56a1f70aeb0441209cda10756a301474bf4.tar.bz2 |
Implement JSONObject#append.
It provides better semantics that accumulate. In particular,
the type of the mapping does not depend on the number of calls
to the function.
Change-Id: Ib8f9d229d8de72d57b25ff9d69c69a61215c2fd7
Diffstat (limited to 'json/src')
-rw-r--r-- | json/src/main/java/org/json/JSONArray.java | 11 | ||||
-rw-r--r-- | json/src/main/java/org/json/JSONObject.java | 47 | ||||
-rw-r--r-- | json/src/test/java/org/json/JSONObjectTest.java | 35 |
3 files changed, 85 insertions, 8 deletions
diff --git a/json/src/main/java/org/json/JSONArray.java b/json/src/main/java/org/json/JSONArray.java index f6801aa..9b5f2b7 100644 --- a/json/src/main/java/org/json/JSONArray.java +++ b/json/src/main/java/org/json/JSONArray.java @@ -187,6 +187,17 @@ public class JSONArray { } /** + * Same as {@link #put}, with added validity checks. + */ + void checkedPut(Object value) throws JSONException { + if (value instanceof Number) { + JSON.checkDouble(((Number) value).doubleValue()); + } + + put(value); + } + + /** * Sets the value at {@code index} to {@code value}, null padding this array * to the required length if necessary. If a value already exists at {@code * index}, it will be replaced. diff --git a/json/src/main/java/org/json/JSONObject.java b/json/src/main/java/org/json/JSONObject.java index 1f474b8..952fb85 100644 --- a/json/src/main/java/org/json/JSONObject.java +++ b/json/src/main/java/org/json/JSONObject.java @@ -283,6 +283,12 @@ public class JSONObject { * mapped to {@code name}. In aggregate, this allows values to be added to a * mapping one at a time. * + * <p> Note that {@link #append(String, Object)} provides better semantics. + * In particular, the mapping for {@code name} will <b>always</b> be a + * {@link JSONArray}. Using {@code accumulate} will result in either a + * {@link JSONArray} or a mapping whose type is the type of {@code value} + * depending on the number of calls to it. + * * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, * Integer, Long, Double, {@link #NULL} or null. May not be {@link * Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}. @@ -293,23 +299,48 @@ public class JSONObject { return put(name, value); } - // check in accumulate, since array.put(Object) doesn't do any checking - if (value instanceof Number) { - JSON.checkDouble(((Number) value).doubleValue()); - } - if (current instanceof JSONArray) { JSONArray array = (JSONArray) current; - array.put(value); + array.checkedPut(value); } else { JSONArray array = new JSONArray(); - array.put(current); - array.put(value); + array.checkedPut(current); + array.checkedPut(value); nameValuePairs.put(name, array); } return this; } + /** + * Appends values to the array mapped to {@code name}. A new {@link JSONArray} + * mapping for {@code name} will be inserted if no mapping exists. If the existing + * mapping for {@code name} is not a {@link JSONArray}, a {@link JSONException} + * will be thrown. + * + * @throws JSONException if {@code name} is {@code null} or if the mapping for + * {@code name} is non-null and is not a {@link JSONArray}. + * + * @hide + */ + public JSONObject append(String name, Object value) throws JSONException { + Object current = nameValuePairs.get(checkName(name)); + + final JSONArray array; + if (current instanceof JSONArray) { + array = (JSONArray) current; + } else if (current == null) { + JSONArray newArray = new JSONArray(); + nameValuePairs.put(name, newArray); + array = newArray; + } else { + throw new JSONException("Key " + name + " is not a JSONArray"); + } + + array.checkedPut(value); + + return this; + } + String checkName(String name) throws JSONException { if (name == null) { throw new JSONException("Names must be non-null"); diff --git a/json/src/test/java/org/json/JSONObjectTest.java b/json/src/test/java/org/json/JSONObjectTest.java index d0a1d2e..e89db94 100644 --- a/json/src/test/java/org/json/JSONObjectTest.java +++ b/json/src/test/java/org/json/JSONObjectTest.java @@ -994,4 +994,39 @@ public class JSONObjectTest extends TestCase { map.put("y", list); assertEquals("{\"x\":\"l\",\"y\":[\"a\",[]]}", new JSONObject(map).toString()); } + + public void testAppendExistingInvalidKey() throws JSONException { + JSONObject object = new JSONObject(); + object.put("foo", 5); + try { + object.append("foo", 6); + fail(); + } catch (JSONException expected) { + } + } + + public void testAppendExistingArray() throws JSONException { + JSONArray array = new JSONArray(); + JSONObject object = new JSONObject(); + object.put("foo", array); + object.append("foo", 5); + assertEquals("[5]", array.toString()); + } + + public void testAppendPutArray() throws JSONException { + JSONObject object = new JSONObject(); + object.append("foo", 5); + assertEquals("{\"foo\":[5]}", object.toString()); + object.append("foo", new JSONArray()); + assertEquals("{\"foo\":[5,[]]}", object.toString()); + } + + public void testAppendNull() { + JSONObject object = new JSONObject(); + try { + object.append(null, 5); + fail(); + } catch (JSONException e) { + } + } } |