From a509a28ed47a5a31e0981a6de3949a7b46c5aa4a Mon Sep 17 00:00:00 2001 From: "John J. Aylward" Date: Sun, 11 Mar 2018 16:59:34 -0400 Subject: [PATCH] Cleans up the name check a little to be more permissive on what can be tagged with the new JSONPropertyName annotation. Also updates the javadoc to reflect the new name allowances --- JSONObject.java | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/JSONObject.java b/JSONObject.java index ca219c9..58138c0 100644 --- a/JSONObject.java +++ b/JSONObject.java @@ -291,15 +291,16 @@ public class JSONObject { * Construct a JSONObject from an Object using bean getters. It reflects on * all of the public methods of the object. For each of the methods with no * parameters and a name starting with "get" or - * "is", the method is invoked, and a key and the value - * returned from the getter method are put into the new JSONObject. + * "is" followed by an uppercase letter, the method is invoked, + * and a key and the value returned from the getter method are put into the + * new JSONObject. *

* The key is formed by removing the "get" or "is" * prefix. If the second remaining character is not upper case, then the * first character is converted to lower case. *

- * Methods that return void as well as static - * methods are ignored. + * Methods that are static, return void, + * have parameters, or are "bridge" methods, are ignored. *

* For example, if an object has a method named "getName", and * if the result of calling object.getName() is @@ -315,6 +316,16 @@ public class JSONObject { * * The resulting JSON object would contain "FullName": "Larry Fine" *

+ * Similarly, the {@link JSONPropertyName} annotation can be used on non- + * get and is methods. We can also override key + * name used in the JSONObject as seen below even though the field would normally + * be ignored: + *

+     * @JSONPropertyName("FullName")
+     * public String fullName() { return this.name; }
+     * 
+ * The resulting JSON object would contain "FullName": "Larry Fine" + *

* The {@link JSONPropertyIgnore} annotation can be used to force the bean property * to not be serialized into JSON. If both {@link JSONPropertyIgnore} and * {@link JSONPropertyName} are defined on the same method, a depth comparison is @@ -1483,9 +1494,7 @@ public class JSONObject { } private boolean isValidMethodName(String name) { - return (name.startsWith("get") || name.startsWith("is")) - && !"getClass".equals(name) - && !"getDeclaringClass".equals(name); + return !"getClass".equals(name) && !"getDeclaringClass".equals(name); } private String getKeyNameFromMethod(Method method) { @@ -1504,9 +1513,9 @@ public class JSONObject { } String key; final String name = method.getName(); - if (name.startsWith("get")) { + if (name.startsWith("get") && name.length() > 3) { key = name.substring(3); - } else if (name.startsWith("is")) { + } else if (name.startsWith("is") && name.length() > 2) { key = name.substring(2); } else { return null; @@ -1514,7 +1523,7 @@ public class JSONObject { // if the first letter in the key is not uppercase, then skip. // This is to maintain backwards compatibility before PR406 // (https://github.com/stleary/JSON-java/pull/406/) - if(key.isEmpty() || Character.isLowerCase(key.charAt(0))) { + if (Character.isLowerCase(key.charAt(0))) { return null; } if (key.length() == 1) { @@ -1568,8 +1577,8 @@ public class JSONObject { } try { - return getAnnotation(m.getDeclaringClass().getSuperclass().getMethod(m.getName(), - m.getParameterTypes()), + return getAnnotation( + c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()), annotationClass); } catch (final SecurityException ex) { return null; @@ -1626,8 +1635,7 @@ public class JSONObject { try { int d = getAnnotationDepth( - m.getDeclaringClass().getSuperclass().getMethod(m.getName(), - m.getParameterTypes()), + c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()), annotationClass); if (d > 0) { // since the annotation was on the superclass, add 1