From 3a81c0a7ad97a74cb15ae0e5061e7adf44e600fe Mon Sep 17 00:00:00 2001 From: T3rm1 Date: Fri, 22 Nov 2024 17:35:05 +0100 Subject: [PATCH] fix: Fields with not null constraint annotations are considered optional if groups attribute is set --- .../v3/core/jackson/ModelResolver.java | 29 +++++++++++++++++-- .../v3/core/converting/ModelPropertyTest.java | 1 + .../v3/core/oas/models/RequiredFields.java | 3 ++ 3 files changed, 30 insertions(+), 3 deletions(-) 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 58181bcdd7..9e01cd0da5 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 @@ -102,6 +102,7 @@ import java.util.Optional; import java.util.Set; import java.util.Objects; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -1532,9 +1533,7 @@ protected void applyBeanValidatorAnnotations(Schema property, Annotation[] annot } } if (parent != null && annotations != null && applyNotNullAnnotations) { - boolean requiredItem = Arrays.stream(annotations).anyMatch(annotation -> - NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName()) - ); + boolean requiredItem = Arrays.stream(annotations).anyMatch(this::requiredByAnnotation); if (requiredItem) { addRequiredItem(parent, property.getName()); } @@ -1591,6 +1590,14 @@ protected void applyBeanValidatorAnnotations(Schema property, Annotation[] annot } } + private boolean requiredByAnnotation(Annotation annotation) { + boolean hasNotNullAnnotation = NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName()); + if (hasNotNullAnnotation && annotation.annotationType().getCanonicalName().contains(".validation.constraints")) { + return !hasGroupsAttribute(annotation); + } + return hasNotNullAnnotation; + } + private boolean resolveSubtypes(Schema model, BeanDescription bean, ModelConverterContext context, JsonView jsonViewAnnotation) { final List types = _intr.findSubtypes(bean.getClassInfo()); if (types == null) { @@ -3078,4 +3085,20 @@ protected Schema buildRefSchemaIfObject(Schema schema, ModelConverterContext con } return result; } + + private boolean hasGroupsAttribute(Annotation annotation) { + return Arrays.stream(annotation.annotationType().getDeclaredMethods()) + .filter(m -> "groups".equals(m.getName())) + .findFirst() + .map(m -> { + try { + return m.invoke(annotation); + } catch (Exception e) { + return null; + } + }) + .map(Class[].class::cast) + .filter(g -> g.length > 0) + .isPresent(); + } } diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/ModelPropertyTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/ModelPropertyTest.java index 4a749918ef..ddfd93e9ff 100644 --- a/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/ModelPropertyTest.java +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/converting/ModelPropertyTest.java @@ -111,6 +111,7 @@ public void testRequiredProperty() { assertTrue(model.getRequired().contains("modeRequired")); assertFalse(model.getRequired().contains("modeNotRequired")); assertFalse(model.getRequired().contains("modeNotRequiredWithAnnotation")); + assertFalse(model.getRequired().contains("requiredByAnnotationWithGroupsAttribute")); } @Test diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/RequiredFields.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/RequiredFields.java index 9a1cf9f8b5..a44fabfc92 100644 --- a/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/RequiredFields.java +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/RequiredFields.java @@ -31,4 +31,7 @@ public class RequiredFields { @Schema(description = "mode not required with annotation", requiredMode = Schema.RequiredMode.NOT_REQUIRED) @NotNull public Long modeNotRequiredWithAnnotation; + + @NotNull(groups = RequiredFields.class) + public Long requiredByAnnotationWithGroupsAttribute; }