summaryrefslogtreecommitdiffstats
path: root/json
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2014-01-10 10:57:33 +0000
committerNarayan Kamath <narayan@google.com>2014-01-13 10:46:06 +0000
commit2ea1d56a1f70aeb0441209cda10756a301474bf4 (patch)
treee8f15bb12ad6a943baa55da8c867198228fcb893 /json
parentb5db5ba4718919c37538fc57cb451c049b8ba8a3 (diff)
downloadlibcore-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')
-rw-r--r--json/src/main/java/org/json/JSONArray.java11
-rw-r--r--json/src/main/java/org/json/JSONObject.java47
-rw-r--r--json/src/test/java/org/json/JSONObjectTest.java35
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) {
+ }
+ }
}