Skip to content

Commit 7b393d5

Browse files
lpandzicfrantuma
authored andcommitted
expanded logic to support collection reference type items validation as well
1 parent fd7ca00 commit 7b393d5

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import java.util.Map;
8787
import java.util.Optional;
8888
import java.util.Set;
89+
import java.util.Objects;
8990
import java.util.stream.Collectors;
9091
import java.util.stream.Stream;
9192

@@ -695,8 +696,8 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
695696
addRequiredItem(model, property.getName());
696697
}
697698
final boolean applyNotNullAnnotations = io.swagger.v3.oas.annotations.media.Schema.RequiredMode.AUTO.equals(requiredMode);
698-
annotations = addGenericTypeAnnotations(propDef, annotations);
699-
applyBeanValidatorAnnotations(property, annotations, model, applyNotNullAnnotations);
699+
annotations = addGenericTypeArgumentAnnotationsForOptionalField(propDef, annotations);
700+
applyBeanValidatorAnnotations(propDef, property, annotations, model, applyNotNullAnnotations);
700701

701702
props.add(property);
702703
}
@@ -898,22 +899,38 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
898899
return model;
899900
}
900901

901-
private Annotation[] addGenericTypeAnnotations(BeanPropertyDefinition propDef, Annotation[] annotations) {
902-
AnnotatedField field = propDef.getField();
903-
if (!field.getType().getRawClass().equals(Optional.class)) {
904-
return annotations;
905-
}
902+
private Annotation[] addGenericTypeArgumentAnnotationsForOptionalField(BeanPropertyDefinition propDef, Annotation[] annotations) {
903+
904+
boolean isNotOptionalType = Optional.ofNullable(propDef)
905+
.map(BeanPropertyDefinition::getField)
906+
.map(AnnotatedField::getAnnotated)
907+
.map(field -> !(field.getType().equals(Optional.class)))
908+
.orElse(false);
906909

907-
java.lang.reflect.AnnotatedType annotatedType = field.getAnnotated().getAnnotatedType();
908-
if (!(annotatedType instanceof AnnotatedParameterizedType)) {
910+
if (isNotOptionalType) {
909911
return annotations;
910912
}
911913

912-
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) annotatedType;
914+
Stream<Annotation> genericTypeArgumentAnnotations = extractGenericTypeArgumentAnnotations(propDef);
915+
return Stream.concat(Stream.of(annotations), genericTypeArgumentAnnotations).toArray(Annotation[]::new);
916+
}
917+
918+
private Stream<Annotation> extractGenericTypeArgumentAnnotations(BeanPropertyDefinition propDef) {
919+
return Optional.ofNullable(propDef)
920+
.map(BeanPropertyDefinition::getField)
921+
.map(AnnotatedField::getAnnotated)
922+
.map(this::getGenericTypeArgumentAnnotations)
923+
.orElseGet(Stream::of);
924+
}
913925

914-
Stream<Annotation> genericTypeAnnotations = Stream.of(parameterizedType.getAnnotatedActualTypeArguments())
915-
.flatMap(type -> Stream.of(type.getAnnotations()));
916-
return Stream.concat(Stream.of(annotations), genericTypeAnnotations).toArray(Annotation[]::new);
926+
private Stream<Annotation> getGenericTypeArgumentAnnotations(Field field) {
927+
return Optional.of(field.getAnnotatedType())
928+
.filter(annotatedType -> annotatedType instanceof AnnotatedParameterizedType)
929+
.map(annotatedType -> (AnnotatedParameterizedType) annotatedType)
930+
.map(AnnotatedParameterizedType::getAnnotatedActualTypeArguments)
931+
.map(types -> Stream.of(types)
932+
.flatMap(type -> Stream.of(type.getAnnotations())))
933+
.orElseGet(Stream::of);
917934
}
918935

919936
private boolean shouldResolveEnumAsRef(io.swagger.v3.oas.annotations.media.Schema resolvedSchemaAnnotation) {
@@ -1309,6 +1326,15 @@ private AnnotatedType removeJsonIdentityAnnotations(AnnotatedType type) {
13091326
}
13101327
}
13111328

1329+
protected void applyBeanValidatorAnnotations(BeanPropertyDefinition propDef, Schema property, Annotation[] annotations, Schema parent, boolean applyNotNullAnnotations) {
1330+
applyBeanValidatorAnnotations(property, annotations, parent, applyNotNullAnnotations);
1331+
1332+
if (Objects.nonNull(property.getItems())) {
1333+
Annotation[] genericTypeArgumentAnnotations = extractGenericTypeArgumentAnnotations(propDef).toArray(Annotation[]::new);
1334+
applyBeanValidatorAnnotations(property.getItems(), genericTypeArgumentAnnotations, property, applyNotNullAnnotations);
1335+
}
1336+
}
1337+
13121338
protected void applyBeanValidatorAnnotations(Schema property, Annotation[] annotations, Schema parent, boolean applyNotNullAnnotations) {
13131339
Map<String, Annotation> annos = new HashMap<>();
13141340
if (annotations != null) {

modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/BeanValidationsModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class BeanValidationsModel {
3737
protected Integer birthYear;
3838

3939
@Size(min = 2, max = 10)
40-
private List<String> items;
40+
private List<@Size(min = 3, max = 4) String> items;
4141

4242
private Optional<@Size(min= 1, max=10) String> optionalValue;
4343

modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/BeanValidatorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public void readBeanValidatorTest() {
4343
final ArraySchema items = (ArraySchema) properties.get("items");
4444
Assert.assertEquals((int) items.getMinItems(), 2);
4545
Assert.assertEquals((int) items.getMaxItems(), 10);
46+
Assert.assertEquals((int) items.getItems().getMinLength(), 3);
47+
Assert.assertEquals((int) items.getItems().getMaxLength(), 4);
4648

4749
final StringSchema optionalValue = (StringSchema) properties.get("optionalValue");
4850
Assert.assertEquals((int) optionalValue.getMinLength(), 1);

0 commit comments

Comments
 (0)