Repository: wicket Updated Branches: refs/heads/wicket-7.x b915427b8 -> 59b853d0c
Porting of https://github.com/openjson/openjson/issues/7 Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/cb7fc6e7 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/cb7fc6e7 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/cb7fc6e7 Branch: refs/heads/wicket-7.x Commit: cb7fc6e7ac60decad639519547c7dcade1b7ecfe Parents: b915427 Author: Andrea Del Bene <[email protected]> Authored: Fri Apr 7 12:49:33 2017 +0200 Committer: Andrea Del Bene <[email protected]> Committed: Sat Apr 15 16:44:53 2017 +0200 ---------------------------------------------------------------------- .../org/apache/wicket/ajax/json/JSONArray.java | 28 ++-- .../org/apache/wicket/ajax/json/JSONObject.java | 160 ++++++++----------- .../apache/wicket/ajax/json/JSONStringer.java | 49 ++++-- .../apache/wicket/ajax/json/JSONTokener.java | 8 +- .../org/apache/wicket/ajax/json/XMLTokener.java | 2 +- 5 files changed, 120 insertions(+), 127 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/cb7fc6e7/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java index 081686d..7b07765 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java @@ -21,7 +21,6 @@ import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Map; import org.apache.wicket.WicketRuntimeException; @@ -96,6 +95,7 @@ public class JSONArray { if (object instanceof JSONArray) { values = ((JSONArray) object).values; } else { + //noinspection ConstantConditions throw JSON.typeMismatch(object, "JSONArray"); } } @@ -714,9 +714,7 @@ public class JSONArray { @Override public String toString() { try { - JSONStringer stringer = new JSONStringer(); - writeTo(stringer); - return stringer.toString(); + return toString(new JSONStringer()); } catch (JSONException e) { return null; } @@ -737,17 +735,23 @@ public class JSONArray { * @throws JSONException Only if there is a coding error. */ public String toString(int indentSpaces) throws JSONException { - JSONStringer stringer = new JSONStringer(indentSpaces); - writeTo(stringer); - return stringer.toString(); + return toString(new JSONStringer(indentSpaces)); } - void writeTo(JSONStringer stringer) throws JSONException { + /** + * Encodes this array using {@link JSONStringer} provided + * + * @param stringer - {@link JSONStringer} to be used for serialization + * @return The string representation of this. + * @throws JSONException On internal errors. Shouldn't happen. + */ + public String toString(JSONStringer stringer) throws JSONException { stringer.array(); for (Object value : values) { stringer.value(value); } stringer.endArray(); + return stringer.toString(); } @Override @@ -766,12 +770,4 @@ public class JSONArray { public Writer write(Writer writer){ throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); } - - public JSONArray put(Map map){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public JSONArray put(int integer, Map map){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } } http://git-wip-us.apache.org/repos/asf/wicket/blob/cb7fc6e7/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONObject.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONObject.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONObject.java index 6058311..9834410 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONObject.java +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONObject.java @@ -19,20 +19,15 @@ package org.apache.wicket.ajax.json; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; -import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.TreeMap; -import org.apache.wicket.WicketRuntimeException; - // Note: this class was written without inspecting the non-free org.json sourcecode. /** @@ -116,7 +111,7 @@ public class JSONObject { // at least make the broken equals(null) consistent with Objects.hashCode(null). @Override public int hashCode() { - return Objects.hashCode(null); + return 0; } @Override @@ -145,17 +140,19 @@ public class JSONObject { /* (accept a raw type for API compatibility) */ public JSONObject(Map copyFrom) { this(); - Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom; - for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) { + if (copyFrom != null) { + Map<?, ?> contentsTyped = copyFrom; + for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) { /* * Deviate from the original by checking that keys are non-null and * of the proper type. (We still defer validating the values). */ - String key = (String) entry.getKey(); - if (key == null) { - throw new NullPointerException("key == null"); + String key = (String) entry.getKey(); + if (key == null) { + throw new NullPointerException("key == null"); + } + nameValuePairs.put(key, wrap(entry.getValue())); } - nameValuePairs.put(key, wrap(entry.getValue())); } } @@ -218,25 +215,38 @@ public class JSONObject { * @throws JSONException If there is an exception while reading the bean */ public JSONObject(Object bean) throws JSONException { - this(propertiesAsMap(bean)); + this(bean instanceof JSONObject ? ((JSONObject)bean).nameValuePairs : propertiesAsMap(bean)); } - private static Map<String, Object> propertiesAsMap(Object bean) - throws JSONException { - Map<String, Object> props = new TreeMap<String, Object>(); - try{ - PropertyDescriptor[] properties = Introspector.getBeanInfo(bean.getClass(), Object.class) - .getPropertyDescriptors(); - for (int i = 0; i < properties.length; i++) { - PropertyDescriptor propertyDescriptor = properties[i]; - props.put(propertyDescriptor.getDisplayName(), propertyDescriptor.getReadMethod().invoke(bean)); - } - }catch(IntrospectionException | InvocationTargetException | IllegalAccessException e){ - throw new JSONException(e); - } + private static Map<String, Object> propertiesAsMap(Object bean) throws JSONException { + Map<String, Object> props = new TreeMap<String, Object>(); + try { + PropertyDescriptor[] properties = Introspector.getBeanInfo(bean.getClass(), Object.class) + .getPropertyDescriptors(); + for (PropertyDescriptor prop : properties) { + Object v = prop.getReadMethod().invoke(bean); + props.put(prop.getDisplayName(), wrap(v)); + } + } catch (IllegalAccessException e) { + throw new JSONException(e); + } catch (IntrospectionException e) { + throw new JSONException(e); + } catch (InvocationTargetException e) { + throw new JSONException(e); + } return props; } + public static String[] getNames(JSONObject x) { + Set<String> names = x.keySet(); + String[] r = new String[names.size()]; + int i = 0; + for (String name : names) { + r[i++] = name; + } + return r; + } + /** * Returns the number of name/value mappings in this object. * @@ -313,6 +323,10 @@ public class JSONObject { * Integer, Long, Double, {@link #NULL}, or {@code null}. May not be * {@link Double#isNaN() NaNs} or {@link Double#isInfinite() * infinities}. + * If value is Map or Collection the value is wrapped using + * corresponding JSONObject(map) or JSONArray(collection) object. + * This behavior is considered unsafe and is added for compatibility + * with original 'org.json' package only. * @return this object. * @throws JSONException if the value is an invalid double (infinite or NaN). */ @@ -321,11 +335,16 @@ public class JSONObject { nameValuePairs.remove(name); return this; } + Object valueToPut = value; if (value instanceof Number) { // deviate from the original by checking all Numbers, not just floats & doubles JSON.checkDouble(((Number) value).doubleValue()); + } else if (value instanceof Collection) { + valueToPut = new JSONArray((Collection) value); + } else if (value instanceof Map) { + valueToPut = new JSONObject((Map)value); } - nameValuePairs.put(checkName(name), value); + nameValuePairs.put(checkName(name), valueToPut); return this; } @@ -836,9 +855,7 @@ public class JSONObject { @Override public String toString() { try { - JSONStringer stringer = new JSONStringer(); - writeTo(stringer); - return stringer.toString(); + return toString(new JSONStringer()); } catch (JSONException e) { return null; } @@ -862,17 +879,23 @@ public class JSONObject { * @throws JSONException On internal errors. Shouldn't happen. */ public String toString(int indentSpaces) throws JSONException { - JSONStringer stringer = new JSONStringer(indentSpaces); - writeTo(stringer); - return stringer.toString(); + return toString(new JSONStringer(indentSpaces)); } - void writeTo(JSONStringer stringer) throws JSONException { + /** + * Encodes this object using {@link JSONStringer} provided + * + * @param stringer - {@link JSONStringer} to be used for serialization + * @return The string representation of this. + * @throws JSONException On internal errors. Shouldn't happen. + */ + public String toString(JSONStringer stringer) throws JSONException { stringer.object(); for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) { - stringer.key(entry.getKey()).value(entry.getValue()); + stringer.entry(entry); } stringer.endObject(); + return stringer.toString(); } /** @@ -897,7 +920,7 @@ public class JSONObject { } long longValue = number.longValue(); - if (doubleValue == (double) longValue) { + if (doubleValue == longValue) { return Long.toString(longValue); } @@ -936,7 +959,8 @@ public class JSONObject { * If the object is an array or {@code Collection}, returns an equivalent {@code JSONArray}. * If the object is a {@code Map}, returns an equivalent {@code JSONObject}. * If the object is a primitive wrapper type or {@code String}, returns the object. - * Otherwise if the object is from a {@code java} package, returns the result of {@code toString}. + * If the object is from a {@code java} package, returns the result of {@code toString}. + * If the object is some other kind of object then it is assumed to be a bean and is converted to a JSONObject. * If wrapping fails, returns null. * * @param o The object to wrap. @@ -972,69 +996,13 @@ public class JSONObject { o instanceof String) { return o; } - if (o.getClass().getPackage().getName().startsWith("java.")) { + if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?>) { return o.toString(); + } else { + return new JSONObject(o); } } catch (Exception ignored) { } return null; } - - // Methods removed due to switch to open-json - - public Writer write(Writer writer){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public String valueToString(Object object){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public void testValidity(Object object){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public Object stringToValue(String string){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public Writer quote(String string, Writer writer){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public JSONObject putOnce(String string, Object object){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public JSONObject put(String string, Map map){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public JSONObject put(String string, Collection collection){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public JSONObject increment(String string){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public String[] getNames(Object object){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public String[] getNames(JSONObject jsonObject){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public String doubleToString(double dou){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public JSONObject(String string, Locale locale){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } - - public JSONObject(Object object, String[] stringarr){ - throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); - } } http://git-wip-us.apache.org/repos/asf/wicket/blob/cb7fc6e7/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java index 5085995..78aa79f 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java @@ -19,6 +19,7 @@ package org.apache.wicket.ajax.json; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; // Note: this class was written without inspecting the non-free org.json sourcecode. @@ -58,12 +59,12 @@ import java.util.List; * Item 17, "Design and Document or inheritance or else prohibit it" for further * information. */ -public class JSONStringer extends JSONWriter{ +public class JSONStringer { /** * The output data, containing at most one top-level array or object. */ - final StringBuilder out = new StringBuilder(); + final protected StringBuilder out = new StringBuilder(); /** * Lexical scoping elements within this stringer, necessary to insert the @@ -237,19 +238,24 @@ public class JSONStringer extends JSONWriter{ } if (value instanceof JSONArray) { - ((JSONArray) value).writeTo(this); + ((JSONArray) value).toString(this); return this; } else if (value instanceof JSONObject) { - ((JSONObject) value).writeTo(this); + ((JSONObject) value).toString(this); return this; } beforeValue(); + if (value instanceof JSONString) { + out.append(((JSONString) value).toJSONString()); + return this; + } + if (value == null - || value instanceof Boolean - || value == JSONObject.NULL) { + || value instanceof Boolean + || value == JSONObject.NULL) { out.append(value); } else if (value instanceof Number) { @@ -258,7 +264,7 @@ public class JSONStringer extends JSONWriter{ } else { // Hack to make it possible that the value is not surrounded by quotes. (Used for JavaScript function calls) // Example: { "name": "testkey", "value": window.myfunction() } - if (value.getClass().getSimpleName().contains("JsonFunction")) { + if (value.getClass().getSimpleName().contains("JSONFunction")) { // note that no escaping of quotes (or anything else) is done in this case. // that is fine because the only way to get to this point is to // explicitly put a special kind of object into the JSON data structure. @@ -320,6 +326,20 @@ public class JSONStringer extends JSONWriter{ return this; } + /** + * Encodes {@code key}/{@code value} pair to this stringer. + * + * @param entry The entry to encode. + * @return this stringer. + * @throws JSONException If we have an internal error. Shouldn't happen. + */ + public JSONStringer entry(Map.Entry<String, Object> entry) { + if (!JSONObject.NULL.equals(entry.getValue())) { + this.key(entry.getKey()).value(entry.getValue()); + } + return this; + } + private void string(String value) { out.append("\""); char currentChar = 0; @@ -393,6 +413,18 @@ public class JSONStringer extends JSONWriter{ } /** + * Creates String representation of the key (property name) to this stringer + * Override this method to provide your own representation of the name. + * + * @param name the name of the forthcoming value. + * @return this stringer. + */ + protected JSONStringer createKey(String name) { + string(name); + return this; + } + + /** * Encodes the key (property name) to this stringer. * * @param name the name of the forthcoming value. May not be null. @@ -404,8 +436,7 @@ public class JSONStringer extends JSONWriter{ throw new JSONException("Names must be non-null"); } beforeKey(); - string(name); - return this; + return createKey(name); } /** http://git-wip-us.apache.org/repos/asf/wicket/blob/cb7fc6e7/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java index bc3e68a..ce884df 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java @@ -438,13 +438,13 @@ public class JSONTokener { throw syntaxError("Unterminated array"); case ']': if (hasTrailingSeparator) { - result.put((Collection<?>)null); + result.put(null); } return result; case ',': case ';': /* A separator without a value first means "null". */ - result.put((Collection<?>)null); + result.put(null); hasTrailingSeparator = true; continue; default: @@ -606,12 +606,10 @@ public class JSONTokener { * input is exhausted. * * @param thru The string to skip over. - * @return boolean */ - public boolean skipPast(String thru) { + public void skipPast(String thru) { int thruStart = in.indexOf(thru, pos); pos = thruStart == -1 ? in.length() : (thruStart + thru.length()); - return true; } /** http://git-wip-us.apache.org/repos/asf/wicket/blob/cb7fc6e7/wicket-core/src/main/java/org/apache/wicket/ajax/json/XMLTokener.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/XMLTokener.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/XMLTokener.java index a1d8ed7..141777e 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/XMLTokener.java +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/XMLTokener.java @@ -49,7 +49,7 @@ public class XMLTokener extends JSONTokener throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); } - public boolean skipPast(String to) throws JSONException + public void skipPast(String to) throws JSONException { throw new WicketRuntimeException(JsonConstants.OPEN_JSON_EXCEPTION); }
