From 2ea1d56a1f70aeb0441209cda10756a301474bf4 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Fri, 10 Jan 2014 10:57:33 +0000 Subject: 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 --- json/src/main/java/org/json/JSONArray.java | 11 +++++++ json/src/main/java/org/json/JSONObject.java | 47 ++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 8 deletions(-) (limited to 'json/src/main/java/org') 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. * + *

Note that {@link #append(String, Object)} provides better semantics. + * In particular, the mapping for {@code name} will always 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"); -- cgit v1.1