From 7ee3089a837cfb0b8eefbaffaaa5d130d680606a Mon Sep 17 00:00:00 2001 From: Michael Edgar Date: Sun, 3 Nov 2024 06:14:11 -0500 Subject: [PATCH] Allow use of `@JsonView` on class Signed-off-by: Michael Edgar --- .../scanner/dataobject/TypeResolver.java | 28 ++++++++++++++++++- .../runtime/scanner/JsonViewTests.java | 3 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java index b80a47162..28ebc2701 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java @@ -42,6 +42,7 @@ import io.smallrye.openapi.api.constants.JsonbConstants; import io.smallrye.openapi.runtime.io.schema.SchemaConstant; import io.smallrye.openapi.runtime.scanner.spi.AnnotationScannerContext; +import io.smallrye.openapi.runtime.util.Annotations; import io.smallrye.openapi.runtime.util.JandexUtil; import io.smallrye.openapi.runtime.util.TypeUtil; @@ -586,7 +587,7 @@ private static boolean isViewable(AnnotationScannerContext context, AnnotationTa return true; } - Type[] applicableViews = context.annotations().getAnnotationValue(propertySource, JacksonConstants.JSON_VIEW); + Type[] applicableViews = getJsonViews(context, propertySource); if (applicableViews != null && applicableViews.length > 0) { return Arrays.stream(applicableViews).anyMatch(activeViews::contains); @@ -595,6 +596,31 @@ private static boolean isViewable(AnnotationScannerContext context, AnnotationTa return true; } + /** + * Find {@literal @}JsonView annotations on the field/method, or on the + * declaring class when the field/method itself it not directly targeted by the + * annotation. + */ + private static Type[] getJsonViews(AnnotationScannerContext context, AnnotationTarget propertySource) { + Annotations annotations = context.annotations(); + + Type[] directViews = annotations.getAnnotationValue(propertySource, JacksonConstants.JSON_VIEW); + + if (directViews != null) { + return directViews; + } + + ClassInfo declaringClass; + + if (propertySource.kind() == Kind.FIELD) { + declaringClass = propertySource.asField().declaringClass(); + } else { + declaringClass = propertySource.asMethod().declaringClass(); + } + + return annotations.getAnnotationValue(declaringClass, JacksonConstants.JSON_VIEW); + } + /** * Determine if the target should be exposed in the API or ignored. Explicitly un-hiding a property * via the @Schema annotation overrides configuration to ignore the same property diff --git a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JsonViewTests.java b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JsonViewTests.java index bf79c2dc5..b99236a52 100644 --- a/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JsonViewTests.java +++ b/extension-jaxrs/src/test/java/io/smallrye/openapi/runtime/scanner/JsonViewTests.java @@ -39,14 +39,15 @@ class InnerBean1 { } @Schema(name = "BeanName") + @com.fasterxml.jackson.annotation.JsonView(Views.Internal.class) // class default is internal class Bean { - @com.fasterxml.jackson.annotation.JsonView(Views.Internal.class) String id; @com.fasterxml.jackson.annotation.JsonView(Views.Public.class) String name; @com.fasterxml.jackson.annotation.JsonView(Views.WriteOnly.class) String secret; @Schema + @com.fasterxml.jackson.annotation.JsonView() InnerBean1 inner1; }