From 7b54511f8dd6246d2231b2ee5139522337c16935 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 31 Jul 2023 18:06:17 +0200 Subject: [PATCH 1/2] Handle class hierarchies when resolving property access. Fix post-JDK 8 Reflection API warnings. --- .../kbss/jsonld/common/BeanAnnotationProcessor.java | 12 ++++++------ .../cvut/kbss/jsonld/common/BeanClassProcessor.java | 4 ++-- .../jsonld/common/JsonLdPropertyAccessResolver.java | 2 +- .../kbss/jsonld/common/PropertyAccessResolver.java | 3 ++- .../common/JsonLdPropertyAccessResolverTest.java | 2 +- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/cz/cvut/kbss/jsonld/common/BeanAnnotationProcessor.java b/src/main/java/cz/cvut/kbss/jsonld/common/BeanAnnotationProcessor.java index 7e16613..69a7725 100644 --- a/src/main/java/cz/cvut/kbss/jsonld/common/BeanAnnotationProcessor.java +++ b/src/main/java/cz/cvut/kbss/jsonld/common/BeanAnnotationProcessor.java @@ -24,14 +24,14 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.*; +import java.util.function.BiPredicate; import java.util.function.Function; -import java.util.function.Predicate; import java.util.stream.Collectors; public class BeanAnnotationProcessor { private static final String[] EMPTY_ARRAY = new String[0]; - private static final Predicate ALWAYS_TRUE = field -> true; + private static final BiPredicate> ALWAYS_TRUE = (f, cls) -> true; private static PropertyAccessResolver propertyAccessResolver = new JsonLdPropertyAccessResolver(); @@ -214,12 +214,12 @@ public static List getSerializableFields(Object object) { return getMarshallableFields(cls, propertyAccessResolver::isReadable); } - private static List getMarshallableFields(Class cls, Predicate filter) { + private static List getMarshallableFields(Class cls, BiPredicate> filter) { final List> classes = getAncestors(cls); final Set fields = new HashSet<>(); for (Class c : classes) { for (Field f : c.getDeclaredFields()) { - if (!isFieldTransient(f) && filter.test(f)) { + if (!isFieldTransient(f) && filter.test(f, cls)) { fields.add(f); } } @@ -416,7 +416,7 @@ public static String getAttributeIdentifier(Field field) { } public static Optional getIdentifierField(Class cls) { - return getMarshallableFields(cls, f -> f.isAnnotationPresent(Id.class)).stream().findFirst(); + return getMarshallableFields(cls, (f, c) -> f.isAnnotationPresent(Id.class)).stream().findFirst(); } /** @@ -431,7 +431,7 @@ public static Optional getInstanceIdentifier(Object instance) { for (Class cls : classes) { for (Field f : cls.getDeclaredFields()) { if (f.getDeclaredAnnotation(Id.class) != null) { - if (!f.isAccessible()) { + if (!f.canAccess(instance)) { f.setAccessible(true); } try { diff --git a/src/main/java/cz/cvut/kbss/jsonld/common/BeanClassProcessor.java b/src/main/java/cz/cvut/kbss/jsonld/common/BeanClassProcessor.java index 7c4c5d8..f7bb102 100644 --- a/src/main/java/cz/cvut/kbss/jsonld/common/BeanClassProcessor.java +++ b/src/main/java/cz/cvut/kbss/jsonld/common/BeanClassProcessor.java @@ -39,7 +39,7 @@ private BeanClassProcessor() { */ public static Object getFieldValue(Field field, Object instance) { Objects.requireNonNull(field); - if (!field.isAccessible()) { + if (!field.canAccess(instance)) { field.setAccessible(true); } try { @@ -58,7 +58,7 @@ public static Object getFieldValue(Field field, Object instance) { */ public static void setFieldValue(Field field, Object instance, Object value) { Objects.requireNonNull(field); - if (!field.isAccessible()) { + if (!field.canAccess(instance)) { field.setAccessible(true); } try { diff --git a/src/main/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolver.java b/src/main/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolver.java index c784a37..eedd9b5 100644 --- a/src/main/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolver.java +++ b/src/main/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolver.java @@ -28,7 +28,7 @@ public class JsonLdPropertyAccessResolver implements PropertyAccessResolver { @Override - public boolean isReadable(Field field) { + public boolean isReadable(Field field, Class objectClass) { Objects.requireNonNull(field); final JsonLdProperty annotation = field.getAnnotation(JsonLdProperty.class); return annotation == null || annotation.access() != JsonLdProperty.Access.WRITE_ONLY || diff --git a/src/main/java/cz/cvut/kbss/jsonld/common/PropertyAccessResolver.java b/src/main/java/cz/cvut/kbss/jsonld/common/PropertyAccessResolver.java index ad5f91e..8f1af79 100644 --- a/src/main/java/cz/cvut/kbss/jsonld/common/PropertyAccessResolver.java +++ b/src/main/java/cz/cvut/kbss/jsonld/common/PropertyAccessResolver.java @@ -25,9 +25,10 @@ public interface PropertyAccessResolver { * Resolves whether value of the specified field is readable for serialization. * * @param field Field to check + * @param objectClass Type of the object being serialized * @return Whether the field is readable */ - boolean isReadable(Field field); + boolean isReadable(Field field, Class objectClass); /** * Resolves whether the specified field is writeable by deserialization. diff --git a/src/test/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolverTest.java b/src/test/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolverTest.java index 5f82ed3..c814781 100644 --- a/src/test/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolverTest.java +++ b/src/test/java/cz/cvut/kbss/jsonld/common/JsonLdPropertyAccessResolverTest.java @@ -39,7 +39,7 @@ class JsonLdPropertyAccessResolverTest { "types, true", "id, true"}) void isReadable(String fieldName, boolean result) throws Exception { - assertEquals(result, sut.isReadable(TestClass.class.getDeclaredField(fieldName))); + assertEquals(result, sut.isReadable(TestClass.class.getDeclaredField(fieldName), TestClass.class)); } @ParameterizedTest From 419c84ce3852d12c317194f863d437f778525fe8 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 31 Jul 2023 18:07:30 +0200 Subject: [PATCH 2/2] [0.13.1] Bump version, update changelog. --- CHANGELOG.md | 3 +++ pom.xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b185a43..60d5d4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # JB4JSON-LD Changelog +## 0.13.1 - 2023-07-31 +- Better handle class hierarchies when resolving property access. + ## 0.13.0 - 2023-07-31 - Make `BeanAnnotationProcessor.getAncestors` public. - **Breaking change:** Set Java 11 as minimum Java version. diff --git a/pom.xml b/pom.xml index 9e8c41b..0702465 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jsonld jb4jsonld - 0.13.0 + 0.13.1 JB4JSON-LD Java Binding for JSON-LD allows serialization and deserialization of Java POJOs to/from JSON-LD. This is the core implementation, which has to be integrated with Jackson, Jersey etc.