Skip to content

Commit 79584cc

Browse files
lpandzicfrantuma
authored andcommitted
added support for generic type bean validation annotations
1 parent 7b20fd9 commit 79584cc

File tree

3 files changed

+59
-101
lines changed

3 files changed

+59
-101
lines changed

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

Lines changed: 38 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,38 @@
11
package io.swagger.v3.core.jackson;
22

3-
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
4-
import com.fasterxml.jackson.annotation.JsonIdentityReference;
5-
import com.fasterxml.jackson.annotation.JsonIgnore;
6-
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
7-
import com.fasterxml.jackson.annotation.JsonProperty;
8-
import com.fasterxml.jackson.annotation.JsonTypeInfo;
9-
import com.fasterxml.jackson.annotation.JsonTypeName;
10-
import com.fasterxml.jackson.annotation.JsonUnwrapped;
11-
import com.fasterxml.jackson.annotation.JsonValue;
12-
import com.fasterxml.jackson.annotation.JsonView;
13-
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
14-
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
15-
import com.fasterxml.jackson.databind.AnnotationIntrospector;
16-
import com.fasterxml.jackson.databind.BeanDescription;
17-
import com.fasterxml.jackson.databind.JavaType;
18-
import com.fasterxml.jackson.databind.ObjectMapper;
19-
import com.fasterxml.jackson.databind.PropertyMetadata;
20-
import com.fasterxml.jackson.databind.SerializationFeature;
3+
import static io.swagger.v3.core.jackson.JAXBAnnotationsHelper.JAXB_DEFAULT;
4+
import static io.swagger.v3.core.util.RefUtils.constructRef;
5+
6+
import javax.validation.constraints.*;
7+
import javax.xml.bind.annotation.*;
8+
import java.io.IOException;
9+
import java.lang.annotation.Annotation;
10+
import java.lang.reflect.*;
11+
import java.math.BigDecimal;
12+
import java.util.*;
13+
import java.util.stream.Collectors;
14+
import java.util.stream.Stream;
15+
16+
import com.fasterxml.jackson.annotation.*;
17+
import com.fasterxml.jackson.databind.*;
2118
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
22-
import com.fasterxml.jackson.databind.introspect.Annotated;
23-
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
24-
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
25-
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
26-
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
27-
import com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder;
19+
import com.fasterxml.jackson.databind.introspect.*;
2820
import com.fasterxml.jackson.databind.jsontype.NamedType;
2921
import com.fasterxml.jackson.databind.util.Annotations;
3022
import io.swagger.v3.core.converter.AnnotatedType;
3123
import io.swagger.v3.core.converter.ModelConverter;
3224
import io.swagger.v3.core.converter.ModelConverterContext;
33-
import io.swagger.v3.core.util.AnnotationsUtils;
34-
import io.swagger.v3.core.util.Constants;
35-
import io.swagger.v3.core.util.Json;
36-
import io.swagger.v3.core.util.ObjectMapperFactory;
37-
import io.swagger.v3.core.util.ReferenceTypeUtils;
38-
import io.swagger.v3.core.util.PrimitiveType;
39-
import io.swagger.v3.core.util.ReflectionUtils;
25+
import io.swagger.v3.core.util.*;
4026
import io.swagger.v3.oas.annotations.Hidden;
41-
import io.swagger.v3.oas.annotations.media.DiscriminatorMapping;
42-
import io.swagger.v3.oas.annotations.media.PatternProperties;
43-
import io.swagger.v3.oas.annotations.media.PatternProperty;
44-
import io.swagger.v3.oas.annotations.media.SchemaProperties;
45-
import io.swagger.v3.oas.annotations.media.SchemaProperty;
27+
import io.swagger.v3.oas.annotations.media.*;
4628
import io.swagger.v3.oas.models.Components;
4729
import io.swagger.v3.oas.models.ExternalDocumentation;
48-
import io.swagger.v3.oas.models.media.ArraySchema;
49-
import io.swagger.v3.oas.models.media.ComposedSchema;
50-
import io.swagger.v3.oas.models.media.Discriminator;
51-
import io.swagger.v3.oas.models.media.IntegerSchema;
52-
import io.swagger.v3.oas.models.media.MapSchema;
53-
import io.swagger.v3.oas.models.media.NumberSchema;
54-
import io.swagger.v3.oas.models.media.ObjectSchema;
55-
import io.swagger.v3.oas.models.media.Schema;
56-
import io.swagger.v3.oas.models.media.StringSchema;
57-
import io.swagger.v3.oas.models.media.UUIDSchema;
58-
import io.swagger.v3.oas.models.media.XML;
30+
import io.swagger.v3.oas.models.media.*;
5931
import org.apache.commons.lang3.StringUtils;
6032
import org.apache.commons.lang3.math.NumberUtils;
6133
import org.slf4j.Logger;
6234
import org.slf4j.LoggerFactory;
6335

64-
import javax.validation.constraints.DecimalMax;
65-
import javax.validation.constraints.DecimalMin;
66-
import javax.validation.constraints.Max;
67-
import javax.validation.constraints.Min;
68-
import javax.validation.constraints.Pattern;
69-
import javax.validation.constraints.Size;
70-
import javax.xml.bind.annotation.XmlElementRef;
71-
import javax.xml.bind.annotation.XmlElementRefs;
72-
import javax.xml.bind.annotation.XmlAccessType;
73-
import javax.xml.bind.annotation.XmlAccessorType;
74-
import javax.xml.bind.annotation.XmlElement;
75-
import javax.xml.bind.annotation.XmlAttribute;
76-
import javax.xml.bind.annotation.XmlRootElement;
77-
import javax.xml.bind.annotation.XmlSchema;
78-
import java.io.IOException;
79-
import java.lang.annotation.Annotation;
80-
import java.lang.reflect.Field;
81-
import java.lang.reflect.InvocationTargetException;
82-
import java.lang.reflect.Method;
83-
import java.lang.reflect.Type;
84-
import java.math.BigDecimal;
85-
import java.util.ArrayList;
86-
import java.util.Arrays;
87-
import java.util.Collection;
88-
import java.util.Collections;
89-
import java.util.HashMap;
90-
import java.util.HashSet;
91-
import java.util.Iterator;
92-
import java.util.LinkedHashMap;
93-
import java.util.List;
94-
import java.util.Map;
95-
import java.util.Optional;
96-
import java.util.Set;
97-
import java.util.stream.Collectors;
98-
import java.util.stream.Stream;
99-
100-
import static io.swagger.v3.core.jackson.JAXBAnnotationsHelper.JAXB_DEFAULT;
101-
import static io.swagger.v3.core.util.RefUtils.constructRef;
102-
10336
public class ModelResolver extends AbstractModelConverter implements ModelConverter {
10437

10538
Logger LOGGER = LoggerFactory.getLogger(ModelResolver.class);
@@ -703,6 +636,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
703636
addRequiredItem(model, property.getName());
704637
}
705638
final boolean applyNotNullAnnotations = io.swagger.v3.oas.annotations.media.Schema.RequiredMode.AUTO.equals(requiredMode);
639+
annotations = addGenericTypeAnnotations(propDef, annotations);
706640
applyBeanValidatorAnnotations(property, annotations, model, applyNotNullAnnotations);
707641

708642
props.add(property);
@@ -905,6 +839,24 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
905839
return model;
906840
}
907841

842+
private Annotation[] addGenericTypeAnnotations(BeanPropertyDefinition propDef, Annotation[] annotations) {
843+
AnnotatedField field = propDef.getField();
844+
if (!field.getType().getRawClass().equals(Optional.class)) {
845+
return annotations;
846+
}
847+
848+
java.lang.reflect.AnnotatedType annotatedType = field.getAnnotated().getAnnotatedType();
849+
if (!(annotatedType instanceof AnnotatedParameterizedType)) {
850+
return annotations;
851+
}
852+
853+
AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) annotatedType;
854+
855+
Stream<Annotation> genericTypeAnnotations = Stream.of(parameterizedType.getAnnotatedActualTypeArguments())
856+
.flatMap(type -> Stream.of(type.getAnnotations()));
857+
return Stream.concat(Stream.of(annotations), genericTypeAnnotations).toArray(Annotation[]::new);
858+
}
859+
908860
private boolean shouldResolveEnumAsRef(io.swagger.v3.oas.annotations.media.Schema resolvedSchemaAnnotation) {
909861
return (resolvedSchemaAnnotation != null && resolvedSchemaAnnotation.enumAsRef()) || ModelResolver.enumsAsRef;
910862
}

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
package io.swagger.v3.core.oas.models;
22

3-
import javax.validation.constraints.DecimalMax;
4-
import javax.validation.constraints.DecimalMin;
5-
import javax.validation.constraints.Max;
6-
import javax.validation.constraints.Min;
7-
import javax.validation.constraints.NotNull;
8-
import javax.validation.constraints.Pattern;
9-
import javax.validation.constraints.Size;
3+
import javax.validation.constraints.*;
104
import java.util.List;
5+
import java.util.Optional;
116

127
public class BeanValidationsModel {
138
@NotNull
@@ -38,6 +33,8 @@ public class BeanValidationsModel {
3833
@Size(min = 2, max = 10)
3934
private List<String> items;
4035

36+
private Optional<@Size(min= 1, max=10) String> optionalValue;
37+
4138
public Long getId() {
4239
return id;
4340
}
@@ -117,4 +114,13 @@ public List<String> getItems() {
117114
public void setItems(List<String> items) {
118115
this.items = items;
119116
}
117+
118+
public Optional<String> getOptionalValue() {
119+
return optionalValue;
120+
}
121+
122+
public void setOptionalValue(Optional<String> optionalValue) {
123+
this.optionalValue = optionalValue;
124+
}
125+
120126
}

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
package io.swagger.v3.core.resolving;
22

3+
import java.math.BigDecimal;
4+
import java.util.Map;
5+
36
import io.swagger.v3.core.converter.ModelConverters;
47
import io.swagger.v3.core.oas.models.BeanValidationsModel;
5-
import io.swagger.v3.oas.models.media.ArraySchema;
6-
import io.swagger.v3.oas.models.media.IntegerSchema;
7-
import io.swagger.v3.oas.models.media.NumberSchema;
8-
import io.swagger.v3.oas.models.media.Schema;
9-
import io.swagger.v3.oas.models.media.StringSchema;
8+
import io.swagger.v3.oas.models.media.*;
109
import org.testng.Assert;
1110
import org.testng.annotations.Test;
1211

13-
import java.math.BigDecimal;
14-
import java.util.Map;
15-
1612
public class BeanValidatorTest {
1713

1814
@Test(description = "read bean validations")
@@ -43,5 +39,9 @@ public void readBeanValidatorTest() {
4339
final ArraySchema items = (ArraySchema) properties.get("items");
4440
Assert.assertEquals((int) items.getMinItems(), 2);
4541
Assert.assertEquals((int) items.getMaxItems(), 10);
42+
43+
final StringSchema optionalValue = (StringSchema) properties.get("optionalValue");
44+
Assert.assertEquals((int) optionalValue.getMinLength(), 1);
45+
Assert.assertEquals((int) optionalValue.getMaxLength(), 10);
4646
}
4747
}

0 commit comments

Comments
 (0)