diff --git a/Cookie.java b/Cookie.java index 348dc688d..aeda6c3a2 100644 --- a/Cookie.java +++ b/Cookie.java @@ -24,6 +24,8 @@ of this software and associated documentation files (the "Software"), to deal SOFTWARE. */ +import java.io.Serializable; + /** * Convert a web browser cookie specification to a JSONObject and back. * JSON and Cookies are both notations for name/value pairs. @@ -81,7 +83,7 @@ public static String escape(String string) { public static JSONObject toJSONObject(String string) throws JSONException { String name; JSONObject jo = new JSONObject(); - Object value; + Serializable value; JSONTokener x = new JSONTokener(string); jo.put("name", x.nextTo('=')); x.next('='); diff --git a/JSONArray.java b/JSONArray.java index fbc1a0f73..4718a8691 100644 --- a/JSONArray.java +++ b/JSONArray.java @@ -25,6 +25,7 @@ of this software and associated documentation files (the "Software"), to deal */ import java.io.IOException; +import java.io.Serializable; import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Array; @@ -81,18 +82,18 @@ of this software and associated documentation files (the "Software"), to deal * @author JSON.org * @version 2016-08/15 */ -public class JSONArray implements Iterable { +public class JSONArray implements Iterable, Serializable { /** * The arrayList where the JSONArray's properties are kept. */ - private final ArrayList myArrayList; + private final ArrayList myArrayList; /** * Construct an empty JSONArray. */ public JSONArray() { - this.myArrayList = new ArrayList(); + this.myArrayList = new ArrayList(); } /** @@ -168,12 +169,12 @@ public JSONArray(String source) throws JSONException { * @param collection * A Collection. */ - public JSONArray(Collection collection) { + public JSONArray(Collection collection) { if (collection == null) { - this.myArrayList = new ArrayList(); + this.myArrayList = new ArrayList(); } else { - this.myArrayList = new ArrayList(collection.size()); - for (Object o: collection){ + this.myArrayList = new ArrayList(collection.size()); + for (Serializable o: collection){ this.myArrayList.add(JSONObject.wrap(o)); } } @@ -188,10 +189,16 @@ public JSONArray(Collection collection) { public JSONArray(Object array) throws JSONException { this(); if (array.getClass().isArray()) { - int length = Array.getLength(array); - this.myArrayList.ensureCapacity(length); - for (int i = 0; i < length; i += 1) { - this.put(JSONObject.wrap(Array.get(array, i))); + Class componentType = array.getClass().getComponentType(); + if (Serializable.class.isAssignableFrom(componentType)) { + int length = Array.getLength(array); + this.myArrayList.ensureCapacity(length); + for (int i = 0; i < length; i += 1) { + this.put(JSONObject.wrap((Serializable)Array.get(array, i))); + } + } else { + throw new JSONException( + "JSONArray initial value should be serializable."); } } else { throw new JSONException( @@ -200,7 +207,7 @@ public JSONArray(Object array) throws JSONException { } @Override - public Iterator iterator() { + public Iterator iterator() { return this.myArrayList.iterator(); } @@ -213,8 +220,8 @@ public Iterator iterator() { * @throws JSONException * If there is no value for the index. */ - public Object get(int index) throws JSONException { - Object object = this.opt(index); + public Serializable get(int index) throws JSONException { + Serializable object = this.opt(index); if (object == null) { throw new JSONException("JSONArray[" + index + "] not found."); } @@ -516,7 +523,7 @@ public int length() { * The index must be between 0 and length() - 1. If not, null is returned. * @return An object value, or null if there is no object at that index. */ - public Object opt(int index) { + public Serializable opt(int index) { return (index < 0 || index >= this.length()) ? null : this.myArrayList .get(index); } @@ -1031,7 +1038,7 @@ public JSONArray put(long value) { * @throws NullPointerException * If a key in the map is null */ - public JSONArray put(Map value) { + public JSONArray put(Map value) { return this.put(new JSONObject(value)); } @@ -1046,7 +1053,7 @@ public JSONArray put(Map value) { * @throws JSONException * If the value is non-finite number. */ - public JSONArray put(Object value) { + public JSONArray put(Serializable value) { JSONObject.testValidity(value); this.myArrayList.add(value); return this; @@ -1189,7 +1196,7 @@ public JSONArray put(int index, Map value) throws JSONException { * If the index is negative or if the the value is an invalid * number. */ - public JSONArray put(int index, Object value) throws JSONException { + public JSONArray put(int index, Serializable value) throws JSONException { if (index < 0) { throw new JSONException("JSONArray[" + index + "] not found."); } @@ -1513,15 +1520,15 @@ public Writer write(Writer writer, int indentFactor, int indent) * * @return a java.util.List containing the elements of this array */ - public List toList() { - List results = new ArrayList(this.myArrayList.size()); - for (Object element : this.myArrayList) { + public List toList() { + List results = new ArrayList(this.myArrayList.size()); + for (Serializable element : this.myArrayList) { if (element == null || JSONObject.NULL.equals(element)) { results.add(null); } else if (element instanceof JSONArray) { - results.add(((JSONArray) element).toList()); + results.add((Serializable)((JSONArray) element).toList()); } else if (element instanceof JSONObject) { - results.add(((JSONObject) element).toMap()); + results.add((Serializable)((JSONObject) element).toMap()); } else { results.add(element); } diff --git a/JSONML.java b/JSONML.java index acec7b869..03387e40c 100644 --- a/JSONML.java +++ b/JSONML.java @@ -24,6 +24,8 @@ of this software and associated documentation files (the "Software"), to deal SOFTWARE. */ +import java.io.Serializable; + /** * This provides static methods to convert an XML text into a JSONArray or * JSONObject, and to covert a JSONArray or JSONObject into an XML text using @@ -222,9 +224,13 @@ private static Object parse( } } else { if (ja != null) { - ja.put(token instanceof String - ? keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token) - : token); + if (token instanceof Serializable) { + ja.put(token instanceof String + ? keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token) + : (Serializable)token); + } else { + throw x.syntaxError("Unserializable object"); + } } } } diff --git a/JSONObject.java b/JSONObject.java index 8deb6bae5..03bc75573 100644 --- a/JSONObject.java +++ b/JSONObject.java @@ -27,6 +27,7 @@ of this software and associated documentation files (the "Software"), to deal */ import java.io.IOException; +import java.io.Serializable; import java.io.StringWriter; import java.io.Writer; import java.lang.annotation.Annotation; @@ -99,13 +100,13 @@ of this software and associated documentation files (the "Software"), to deal * @author JSON.org * @version 2016-08-15 */ -public class JSONObject { +public class JSONObject implements Serializable { /** * JSONObject.NULL is equivalent to the value that JavaScript calls null, * whilst Java's null is equivalent to the value that JavaScript calls * undefined. */ - private static final class Null { + private static final class Null implements Serializable { /** * There is only intended to be a single instance of the NULL object, @@ -154,7 +155,7 @@ public String toString() { /** * The map where the JSONObject's properties are kept. */ - private final Map map; + private final Map map; /** * It is sometimes more convenient and less ambiguous to have a @@ -162,7 +163,7 @@ public String toString() { * JSONObject.NULL.equals(null) returns true. * JSONObject.NULL.toString() returns "null". */ - public static final Object NULL = new Null(); + public static final Serializable NULL = new Null(); /** * Construct an empty JSONObject. @@ -174,7 +175,7 @@ public JSONObject() { // implementations to rearrange their items for a faster element // retrieval based on associative access. // Therefore, an implementation mustn't rely on the order of the item. - this.map = new HashMap(); + this.map = new HashMap(); } /** @@ -242,7 +243,7 @@ public JSONObject(JSONTokener x) throws JSONException { throw x.syntaxError("Duplicate key \"" + key + "\""); } // Only add value if non-null - Object value = x.nextValue(); + Serializable value = x.nextValue(); if (value!=null) { this.put(key, value); } @@ -277,16 +278,16 @@ public JSONObject(JSONTokener x) throws JSONException { * @throws NullPointerException * If a key in the map is null */ - public JSONObject(Map m) { + public JSONObject(Map m) { if (m == null) { - this.map = new HashMap(); + this.map = new HashMap(); } else { - this.map = new HashMap(m.size()); - for (final Entry e : m.entrySet()) { + this.map = new HashMap(m.size()); + for (final Entry e : m.entrySet()) { if(e.getKey() == null) { throw new NullPointerException("Null key."); } - final Object value = e.getValue(); + final Serializable value = e.getValue(); if (value != null) { this.map.put(String.valueOf(e.getKey()), wrap(value)); } @@ -377,7 +378,10 @@ public JSONObject(Object object, String names[]) { for (int i = 0; i < names.length; i += 1) { String name = names[i]; try { - this.putOpt(name, c.getField(name).get(object)); + Object value = c.getField(name).get(object); + if (value instanceof Serializable) { + this.putOpt(name, (Serializable)object); + } } catch (Exception ignore) { } } @@ -450,7 +454,7 @@ public JSONObject(String baseName, Locale locale) throws JSONException { * @param initialCapacity initial capacity of the internal map. */ protected JSONObject(int initialCapacity){ - this.map = new HashMap(initialCapacity); + this.map = new HashMap(initialCapacity); } /** @@ -474,9 +478,9 @@ protected JSONObject(int initialCapacity){ * @throws NullPointerException * If the key is null. */ - public JSONObject accumulate(String key, Object value) throws JSONException { + public JSONObject accumulate(String key, Serializable value) throws JSONException { testValidity(value); - Object object = this.opt(key); + Serializable object = this.opt(key); if (object == null) { this.put(key, value instanceof JSONArray ? new JSONArray().put(value) @@ -506,9 +510,9 @@ public JSONObject accumulate(String key, Object value) throws JSONException { * @throws NullPointerException * If the key is null. */ - public JSONObject append(String key, Object value) throws JSONException { + public JSONObject append(String key, Serializable value) throws JSONException { testValidity(value); - Object object = this.opt(key); + Serializable object = this.opt(key); if (object == null) { this.put(key, new JSONArray().put(value)); } else if (object instanceof JSONArray) { @@ -949,7 +953,7 @@ public Set keySet() { * * @return An Entry Set */ - protected Set> entrySet() { + protected Set> entrySet() { return this.map.entrySet(); } @@ -1022,7 +1026,7 @@ public static String numberToString(Number number) throws JSONException { * A key string. * @return An object which is the value, or null if there is no value. */ - public Object opt(String key) { + public Serializable opt(String key) { return key == null ? null : this.map.get(key); } @@ -1491,8 +1495,8 @@ && isValidMethodName(method.getName())) { if (key != null && !key.isEmpty()) { try { final Object result = method.invoke(bean); - if (result != null) { - this.map.put(key, wrap(result)); + if (result != null && result instanceof Serializable) { + this.map.put(key, wrap((Serializable)result)); // we don't use the result anywhere outside of wrap // if it's a resource we should be sure to close it // after calling toString @@ -1805,7 +1809,7 @@ public JSONObject put(String key, Map value) throws JSONException { * @throws NullPointerException * If the key is null. */ - public JSONObject put(String key, Object value) throws JSONException { + public JSONObject put(String key, Serializable value) throws JSONException { if (key == null) { throw new NullPointerException("Null key."); } @@ -1829,7 +1833,7 @@ public JSONObject put(String key, Object value) throws JSONException { * @throws JSONException * if the key is a duplicate */ - public JSONObject putOnce(String key, Object value) throws JSONException { + public JSONObject putOnce(String key, Serializable value) throws JSONException { if (key != null && value != null) { if (this.opt(key) != null) { throw new JSONException("Duplicate key \"" + key + "\""); @@ -1853,7 +1857,7 @@ public JSONObject putOnce(String key, Object value) throws JSONException { * @throws JSONException * If the value is a non-finite number. */ - public JSONObject putOpt(String key, Object value) throws JSONException { + public JSONObject putOpt(String key, Serializable value) throws JSONException { if (key != null && value != null) { return this.put(key, value); } @@ -2155,7 +2159,7 @@ protected static Number stringToNumber(final String val) throws NumberFormatExce */ // Changes to this method must be copied to the corresponding method in // the XML class to keep full support for Android - public static Object stringToValue(String string) { + public static Serializable stringToValue(String string) { if (string.equals("")) { return string; } @@ -2344,7 +2348,7 @@ public static String valueToString(Object value) throws JSONException { * The object to wrap * @return The wrapped value */ - public static Object wrap(Object object) { + public static Serializable wrap(Serializable object) { try { if (object == null) { return NULL; @@ -2361,14 +2365,14 @@ public static Object wrap(Object object) { } if (object instanceof Collection) { - Collection coll = (Collection) object; + Collection coll = (Collection) object; return new JSONArray(coll); } if (object.getClass().isArray()) { return new JSONArray(object); } if (object instanceof Map) { - Map map = (Map) object; + Map map = (Map) object; return new JSONObject(map); } Package objectPackage = object.getClass().getPackage(); @@ -2543,16 +2547,16 @@ public Writer write(Writer writer, int indentFactor, int indent) * * @return a java.util.Map containing the entries of this object */ - public Map toMap() { - Map results = new HashMap(); - for (Entry entry : this.entrySet()) { - Object value; + public Map toMap() { + Map results = new HashMap(); + for (Entry entry : this.entrySet()) { + Serializable value; if (entry.getValue() == null || NULL.equals(entry.getValue())) { value = null; } else if (entry.getValue() instanceof JSONObject) { - value = ((JSONObject) entry.getValue()).toMap(); + value = (Serializable)((JSONObject) entry.getValue()).toMap(); } else if (entry.getValue() instanceof JSONArray) { - value = ((JSONArray) entry.getValue()).toList(); + value = (Serializable)((JSONArray) entry.getValue()).toList(); } else { value = entry.getValue(); } diff --git a/JSONTokener.java b/JSONTokener.java index 36bce45c2..9a78bac94 100644 --- a/JSONTokener.java +++ b/JSONTokener.java @@ -5,6 +5,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.io.Serializable; import java.io.StringReader; /* @@ -418,7 +419,7 @@ public String nextTo(String delimiters) throws JSONException { * * @return An object. */ - public Object nextValue() throws JSONException { + public Serializable nextValue() throws JSONException { char c = this.nextClean(); String string; diff --git a/XML.java b/XML.java index 55362b274..adab1b843 100644 --- a/XML.java +++ b/XML.java @@ -25,6 +25,7 @@ of this software and associated documentation files (the "Software"), to deal */ import java.io.Reader; +import java.io.Serializable; import java.io.StringReader; import java.util.Iterator; @@ -407,7 +408,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, bool */ // To maintain compatibility with the Android API, this method is a direct copy of // the one in JSONObject. Changes made here should be reflected there. - public static Object stringToValue(String string) { + public static Serializable stringToValue(String string) { if (string.equals("")) { return string; }