diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java index 3082974..547bf9c 100644 --- a/src/main/java/org/json/JSONArray.java +++ b/src/main/java/org/json/JSONArray.java @@ -177,6 +177,35 @@ public class JSONArray implements Iterable { } } + /** + * Construct a JSONArray from an Iterable. This is a shallow copy. + * + * @param iter + * A Iterable collection. + */ + public JSONArray(Iterable iter) { + this(); + if (iter == null) { + return; + } + this.addAll(iter); + } + + /** + * Construct a JSONArray from another JSONArray. This is a shallow copy. + * + * @param collection + * A Collection. + */ + public JSONArray(JSONArray array) { + if (array == null) { + this.myArrayList = new ArrayList(); + } else { + this.myArrayList = new ArrayList(array.length()); + this.addAll(array.myArrayList); + } + } + /** * Construct a JSONArray from an array. * @@ -191,6 +220,10 @@ public class JSONArray implements Iterable { */ public JSONArray(Object array) throws JSONException { this(); + if (!array.getClass().isArray()) { + throw new JSONException( + "JSONArray initial value should be a string or collection or array."); + } this.addAll(array); } @@ -210,6 +243,11 @@ public class JSONArray implements Iterable { this.myArrayList = new ArrayList(initialCapacity); } + @Override + protected Object clone() { + return new JSONArray(this.myArrayList); + } + @Override public Iterator iterator() { return this.myArrayList.iterator(); @@ -1165,7 +1203,7 @@ public class JSONArray implements Iterable { } /** - * Put or replace a collection's elements in the JSONArray. + * Put a collection's elements in to the JSONArray. * * @param collection * A Collection. @@ -1175,9 +1213,33 @@ public class JSONArray implements Iterable { this.addAll(collection); return this; } + + /** + * Put an Iterable's elements in to the JSONArray. + * + * @param iter + * A Collection. + * @return this. + */ + public JSONArray putAll(Iterable iter) { + this.addAll(iter); + return this; + } /** - * Put or replace an array's elements in the JSONArray. + * Put a JSONArray's elements in to the JSONArray. + * + * @param array + * A JSONArray. + * @return this. + */ + public JSONArray putAll(JSONArray array) { + this.addAll(array.myArrayList); + return this; + } + + /** + * Put an array's elements in to the JSONArray. * * @param array * Array. If the parameter passed is null, or not an array, an @@ -1520,7 +1582,6 @@ public class JSONArray implements Iterable { return this.myArrayList.isEmpty(); } - /** * Add a collection's elements to the JSONArray. * @@ -1534,6 +1595,18 @@ public class JSONArray implements Iterable { } } + /** + * Add an Iterable's elements to the JSONArray. + * + * @param iter + * An Iterable. + */ + private void addAll(Iterable iter) { + for (Object o: iter){ + this.myArrayList.add(JSONObject.wrap(o)); + } + } + /** * Add an array's elements to the JSONArray. * @@ -1553,6 +1626,12 @@ public class JSONArray implements Iterable { for (int i = 0; i < length; i += 1) { this.put(JSONObject.wrap(Array.get(array, i))); } + } else if (array instanceof JSONArray) { + this.addAll(((JSONArray)array).myArrayList); + } else if (array instanceof Collection) { + this.addAll((Collection)array); + } else if (array instanceof Iterable) { + this.addAll((Iterable)array); } else { throw new JSONException( "JSONArray initial value should be a string or collection or array."); diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 4a322c1..7673157 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -979,9 +979,9 @@ public class JSONArrayTest { JSONArray jsonArray = new JSONArray(str); String expectedStr = str; StringWriter stringWriter = new StringWriter(); - jsonArray.write(stringWriter); - String actualStr = stringWriter.toString(); try { + jsonArray.write(stringWriter); + String actualStr = stringWriter.toString(); JSONArray finalArray = new JSONArray(actualStr); Util.compareActualVsExpectedJsonArrays(jsonArray, finalArray); assertTrue("write() expected " + expectedStr + @@ -1187,4 +1187,71 @@ public class JSONArrayTest { e.getMessage()); } } + + /** + * Verifies that the object constructor can properly handle any supported collection object. + */ + @Test + @SuppressWarnings({ "unchecked", "boxing" }) + public void testObjectConstructor() { + // should copy the array + Object o = new Object[] {2, "test2", true}; + JSONArray a = new JSONArray(o); + assertNotNull("Should not error", a); + assertEquals("length", 3, a.length()); + + // should NOT copy the collection + // this is required for backwards compatibility + o = new ArrayList(); + ((Collection)o).add(1); + ((Collection)o).add("test"); + ((Collection)o).add(false); + try { + a = new JSONArray(o); + assertNull("Should error", a); + } catch (JSONException ex) { + } + + // should NOT copy the JSONArray + // this is required for backwards compatibility + o = a; + try { + a = new JSONArray(o); + assertNull("Should error", a); + } catch (JSONException ex) { + } + } + + /** + * Verifies that the JSONArray constructor properly copies the original. + */ + @Test + public void testJSONArrayConstructor() { + // should copy the array + JSONArray a1 = new JSONArray("[2, \"test2\", true]"); + JSONArray a2 = new JSONArray(a1); + assertNotNull("Should not error", a2); + assertEquals("length", a1.length(), a2.length()); + + for(int i = 0; i < a1.length(); i++) { + assertEquals("index " + i + " are equal", a1.get(i), a2.get(i)); + } + } + + /** + * Verifies that the object constructor can properly handle any supported collection object. + */ + @Test + public void testJSONArrayPutAll() { + // should copy the array + JSONArray a1 = new JSONArray("[2, \"test2\", true]"); + JSONArray a2 = new JSONArray(); + a2.putAll(a1); + assertNotNull("Should not error", a2); + assertEquals("length", a1.length(), a2.length()); + + for(int i = 0; i < a1.length(); i++) { + assertEquals("index " + i + " are equal", a1.get(i), a2.get(i)); + } + } } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 2b43212..51407f0 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -3201,4 +3201,11 @@ public class JSONObjectTest { fail("Expected an exception"); } + @Test + public void testIssue548ObjectWithEmptyJsonArray() { + JSONObject jsonObject = new JSONObject("{\"empty_json_array\": []}"); + assertTrue("missing expected key 'empty_json_array'", jsonObject.has("empty_json_array")); + assertNotNull("'empty_json_array' should be an array", jsonObject.getJSONArray("empty_json_array")); + assertEquals("'empty_json_array' should have a length of 0", 0, jsonObject.getJSONArray("empty_json_array").length()); + } }