From 7b20fd9345f9a289cc2527fe4486552b42c8a586 Mon Sep 17 00:00:00 2001 From: devopsix <58369032+devopsix@users.noreply.github.com> Date: Thu, 27 Oct 2022 20:43:34 +0200 Subject: [PATCH] fix: JsonView annotation ignored for subclasses Forward JsonView annotation when resolving subtypes. Refs: #4239 --- .../v3/core/jackson/ModelResolver.java | 7 +- .../v3/core/resolving/Ticket4239Test.java | 75 +++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/Ticket4239Test.java diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java index 1a43e1fcd2..cfdcf8cbd8 100644 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java @@ -742,7 +742,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context * This must be done after model.setProperties so that the model's set * of properties is available to filter from any subtypes **/ - if (!resolveSubtypes(model, beanDesc, context)) { + if (!resolveSubtypes(model, beanDesc, context, annotatedType.getJsonViewAnnotation())) { model.setDiscriminator(null); } @@ -1370,7 +1370,7 @@ protected void applyBeanValidatorAnnotations(Schema property, Annotation[] annot } } - private boolean resolveSubtypes(Schema model, BeanDescription bean, ModelConverterContext context) { + private boolean resolveSubtypes(Schema model, BeanDescription bean, ModelConverterContext context, JsonView jsonViewAnnotation) { final List types = _intr.findSubtypes(bean.getClassInfo()); if (types == null) { return false; @@ -1398,7 +1398,8 @@ private boolean resolveSubtypes(Schema model, BeanDescription bean, ModelConvert continue; } - final Schema subtypeModel = context.resolve(new AnnotatedType().type(subtypeType)); + final Schema subtypeModel = context.resolve(new AnnotatedType().type(subtypeType) + .jsonViewAnnotation(jsonViewAnnotation)); if ( StringUtils.isBlank(subtypeModel.getName()) || subtypeModel.getName().equals(model.getName())) { diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/Ticket4239Test.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/Ticket4239Test.java new file mode 100644 index 0000000000..f192eb99d9 --- /dev/null +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/Ticket4239Test.java @@ -0,0 +1,75 @@ +package io.swagger.v3.core.resolving; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonView; +import io.swagger.v3.core.converter.AnnotatedType; +import io.swagger.v3.core.converter.ModelConverterContextImpl; +import io.swagger.v3.core.jackson.ModelResolver; +import io.swagger.v3.core.matchers.SerializationMatchers; +import org.testng.annotations.Test; + +import java.lang.annotation.Annotation; + +import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME; + +public class Ticket4239Test extends SwaggerTestBase { + + public interface Input {} + + public interface Output {} + + @JsonTypeInfo(use = NAME) + @JsonSubTypes({ + @JsonSubTypes.Type(value = A1.class), + }) + public static abstract class A { + @JsonView(Input.class) + public String a_in; + @JsonView(Output.class) + public String a_out; + } + + public static class A1 extends A { + @JsonView(Input.class) + public String a1_in; + @JsonView(Output.class) + public String a1_out; + } + + private static final JsonView VIEW_OUTPUT = new JsonView() { + public Class annotationType() { + return JsonView.class; + } + public Class[] value() { + return new Class[] {Output.class}; + } + }; + + @Test + public void testJsonValueSchemaAnnotation() { + + final ModelResolver modelResolver = new ModelResolver(mapper()); + + ModelConverterContextImpl context = new ModelConverterContextImpl(modelResolver); + + AnnotatedType type = new AnnotatedType(Ticket4239Test.A.class).jsonViewAnnotation(VIEW_OUTPUT); + + context.resolve(type); + + SerializationMatchers.assertEqualsToYaml(context.getDefinedModels(), "A1_Output:\n" + + " type: object\n" + + " allOf:\n" + + " - $ref: '#/components/schemas/A_Output'\n" + + " - type: object\n" + + " properties:\n" + + " a1_out:\n" + + " type: string\n" + + "A_Output:\n" + + " type: object\n" + + " properties:\n" + + " a_out:\n" + + " type: string\n"); + + } +}