This is an automated email from the ASF dual-hosted git repository. struberg pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/johnzon.git
The following commit(s) were added to refs/heads/master by this push: new 442b449 JOHNZON-264 move introspection stuff to new BeanUtil 442b449 is described below commit 442b44992ca6dcfc702d64df121d0b969ade5336 Author: Mark Struberg <strub...@apache.org> AuthorDate: Tue Apr 12 10:53:35 2022 +0200 JOHNZON-264 move introspection stuff to new BeanUtil --- .../org/apache/johnzon/core/util/ClassUtil.java | 32 ---------- .../jsonb/DefaultPropertyVisibilityStrategy.java | 6 +- .../mapper/access/FieldAndMethodAccessMode.java | 6 +- .../org/apache/johnzon/mapper/util/BeanUtil.java | 68 +++++++++------------- .../johnzon/mapper/internal/BeanUtilTest.java | 29 ++++++--- 5 files changed, 56 insertions(+), 85 deletions(-) diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/util/ClassUtil.java b/johnzon-core/src/main/java/org/apache/johnzon/core/util/ClassUtil.java index 1eebe6f..1dc189b 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/util/ClassUtil.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/util/ClassUtil.java @@ -58,36 +58,4 @@ public final class ClassUtil { } } - /** - * Calculate the name of a getter based on the name of it's field and the type - * - * @param fieldName - * @param type of the field - * @return "get" or "is" method name for the field - */ - public static String getterName(String fieldName, Class<?> type) { - StringBuilder sb = new StringBuilder(50); - sb.append(type == Boolean.class || type == boolean.class ? "is" : "get"); - sb.append(Character.toUpperCase(fieldName.charAt(0))).append(fieldName.substring(1)); - return sb.toString(); - } - - /** - * Calculate the name of a setter based on the name of it's field - * - * @param fieldName - * @return "set" method name for the field - */ - public static String setterName(String fieldName) { - StringBuilder sb = new StringBuilder(50); - sb.append("set"); - sb.append(Character.toUpperCase(fieldName.charAt(0))).append(fieldName.substring(1)); - return sb.toString(); - } - - public static String capitalizeName(String fieldName) { - StringBuilder sb = new StringBuilder(50); - sb.append(Character.toUpperCase(fieldName.charAt(0))).append(fieldName.substring(1)); - return sb.toString(); - } } \ No newline at end of file diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/DefaultPropertyVisibilityStrategy.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/DefaultPropertyVisibilityStrategy.java index 33e0be5..ff854a7 100644 --- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/DefaultPropertyVisibilityStrategy.java +++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/DefaultPropertyVisibilityStrategy.java @@ -18,8 +18,8 @@ */ package org.apache.johnzon.jsonb; -import org.apache.johnzon.core.util.ClassUtil; import org.apache.johnzon.mapper.Cleanable; +import org.apache.johnzon.mapper.util.BeanUtil; import javax.json.bind.annotation.JsonbProperty; import javax.json.bind.annotation.JsonbVisibility; @@ -60,9 +60,9 @@ class DefaultPropertyVisibilityStrategy implements javax.json.bind.config.Proper // 3.7.1. Scope and Field access strategy // note: we should bind the class since a field of a parent class can have a getter in a child if (!useGetter) { - return !hasMethod(root, ClassUtil.setterName(field.getName())); + return !hasMethod(root, BeanUtil.setterName(field.getName())); } - final String capitalizedName = ClassUtil.capitalizeName(field.getName()); + final String capitalizedName = BeanUtil.capitalize(field.getName()); return !hasMethod(root, "get" + capitalizedName) || hasMethod(root, "is" + capitalizedName); } diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAndMethodAccessMode.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAndMethodAccessMode.java index c06de48..6d3ad42 100644 --- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAndMethodAccessMode.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAndMethodAccessMode.java @@ -24,8 +24,8 @@ import org.apache.johnzon.mapper.Adapter; import org.apache.johnzon.mapper.JohnzonIgnore; import org.apache.johnzon.mapper.JohnzonProperty; import org.apache.johnzon.mapper.ObjectConverter; +import org.apache.johnzon.mapper.util.BeanUtil; -import java.beans.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -109,7 +109,7 @@ public class FieldAndMethodAccessMode extends BaseAccessMode { final Method mr = MethodAccessMode.MethodDecoratedType.class.cast(entry.getValue()).getMethod(); final String fieldName = record ? mr.getName() : - Introspector.decapitalize(mr.getName().startsWith("is") ? + BeanUtil.decapitalize(mr.getName().startsWith("is") ? mr.getName().substring(2) : mr.getName().substring(3)); final Field f = getField(fieldName, clazz); boolean skip = false; @@ -205,7 +205,7 @@ public class FieldAndMethodAccessMode extends BaseAccessMode { for (final Map.Entry<String, Writer> entry : metodWriters.entrySet()) { final Method mr = MethodAccessMode.MethodDecoratedType.class.cast(entry.getValue()).getMethod(); - final String fieldName = Introspector.decapitalize(mr.getName().startsWith("is") ? mr.getName().substring(2) : mr.getName().substring(3)); + final String fieldName = BeanUtil.decapitalize(mr.getName().startsWith("is") ? mr.getName().substring(2) : mr.getName().substring(3)); final Field f = getField(fieldName, clazz); boolean skip = false; if (f != null) { diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/util/ClassUtil.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/util/BeanUtil.java similarity index 65% copy from johnzon-core/src/main/java/org/apache/johnzon/core/util/ClassUtil.java copy to johnzon-mapper/src/main/java/org/apache/johnzon/mapper/util/BeanUtil.java index 1eebe6f..0fd93ac 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/util/ClassUtil.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/util/BeanUtil.java @@ -14,50 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.johnzon.core.util; +package org.apache.johnzon.mapper.util; + /** - * ClassLoader related utils + * Some simple bean introspection methods. + * To avoid a dependency on the awt java.beans.introspector which is a desktop level class. */ -public final class ClassUtil { +public final class BeanUtil { - private ClassUtil() { + private BeanUtil() { // private utility class ct } - /** - * @return either the ThreadContextClassLoader or the CL of this very class if no TCCL exists - */ - public static ClassLoader getClassLoader() { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - if (tccl != null) { - return tccl; - } - - return ClassUtil.class.getClassLoader(); - } - - /** - * @param className to be loaded - * @param ignoreBrokenClasses if {@link NoClassDefFoundError} should be ignored - * @return Class or {@code null} if the class could not be found - */ - public static Class<?> loadClassOptional(String className, boolean ignoreBrokenClasses) { - ClassLoader cl = getClassLoader(); - - try { - return cl.loadClass(className); - } catch (ClassNotFoundException e) { - // all fine, that class is optional! - return null; - } catch (NoClassDefFoundError ncdfe) { - if (ignoreBrokenClasses) { - return null; - } - throw ncdfe; - } - } - /** * Calculate the name of a getter based on the name of it's field and the type * @@ -85,9 +54,30 @@ public final class ClassUtil { return sb.toString(); } - public static String capitalizeName(String fieldName) { + /** + * capitalize according to java beans specification + */ + public static String capitalize(String fieldName) { StringBuilder sb = new StringBuilder(50); sb.append(Character.toUpperCase(fieldName.charAt(0))).append(fieldName.substring(1)); return sb.toString(); } -} \ No newline at end of file + + /** + * capitalize according to java beans specification. + * That is start the given field with a lower case, but only if the 2nd char is not also an uppercase character + * Enabled -> enabled, but URL will remain URL. + */ + public static String decapitalize(String name) { + if (name == null || name.length() == 0) { + return name; + } + + if (name.length() > 1 && Character.isUpperCase(name.charAt(0)) && Character.isUpperCase(name.charAt(1))) { + return name; + } + char[] chars = name.toCharArray(); + chars[0] = Character.toLowerCase(chars[0]); + return new String(chars); + } +} diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/ClassUtilTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/internal/BeanUtilTest.java similarity index 51% rename from johnzon-core/src/test/java/org/apache/johnzon/core/ClassUtilTest.java rename to johnzon-mapper/src/test/java/org/apache/johnzon/mapper/internal/BeanUtilTest.java index 299d146..54396ae 100644 --- a/johnzon-core/src/test/java/org/apache/johnzon/core/ClassUtilTest.java +++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/internal/BeanUtilTest.java @@ -14,25 +14,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.johnzon.core; +package org.apache.johnzon.mapper.internal; -import org.apache.johnzon.core.util.ClassUtil; +import org.apache.johnzon.mapper.util.BeanUtil; import org.junit.Test; import static org.junit.Assert.assertEquals; -public class ClassUtilTest { +public class BeanUtilTest { @Test public void testGetterNames() { - assertEquals("getMyName", ClassUtil.getterName("myName", Integer.class)); - assertEquals("isEnabled", ClassUtil.getterName("enabled", Boolean.class)); - assertEquals("isEnabled", ClassUtil.getterName("enabled", boolean.class)); + assertEquals("getMyName", BeanUtil.getterName("myName", Integer.class)); + assertEquals("isEnabled", BeanUtil.getterName("enabled", Boolean.class)); + assertEquals("isEnabled", BeanUtil.getterName("enabled", boolean.class)); } @Test public void testSetterNames() { - assertEquals("setMyName", ClassUtil.setterName("myName")); - assertEquals("setEnabled", ClassUtil.setterName("enabled")); + assertEquals("setMyName", BeanUtil.setterName("myName")); + assertEquals("setEnabled", BeanUtil.setterName("enabled")); + } + + @Test + public void testCapitalize() { + assertEquals("Enabled", BeanUtil.capitalize("enabled")); + assertEquals("URL", BeanUtil.capitalize("URL")); + assertEquals("Url", BeanUtil.capitalize("url")); + } + + @Test + public void testDecapitalize() { + assertEquals("enabled", BeanUtil.decapitalize("Enabled")); + assertEquals("URL", BeanUtil.decapitalize("URL")); } }