From aeac73b943ae438ce4e7345fb8c3cf896fb573c9 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Wed, 22 Feb 2023 12:45:11 +0100 Subject: [PATCH] #1920 - Support for JSR-303 @Size annotation in property metadata. Using the JSR-303 @Size annotation is now reflected in the property being considered for input type range as well as exposed min and max values. --- .../hateoas/mediatype/PropertyUtils.java | 12 ++++++++---- .../hateoas/mediatype/PropertyUtilsTest.java | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java b/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java index 74e6b1ef..25c8bdbc 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java +++ b/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java @@ -34,6 +34,7 @@ import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; import org.reactivestreams.Publisher; import org.springframework.beans.BeanUtils; @@ -558,6 +559,7 @@ public class PropertyUtils { Map, String> typeMap = new HashMap<>(); typeMap.put(Email.class, "email"); + typeMap.put(Size.class, "range"); if (URL_ANNOTATION != null) { typeMap.put(URL_ANNOTATION, "url"); @@ -617,8 +619,9 @@ public class PropertyUtils { @Override public Number getMin() { - return Optional.ofNullable(RANGE_ANNOTATION) // - .flatMap(it -> getAnnotationAttribute(it, "min", Number.class)) // + return getAnnotationAttribute(Size.class, "min", Number.class) // + .or(() -> Optional.ofNullable(RANGE_ANNOTATION) + .flatMap(it -> getAnnotationAttribute(it, "min", Number.class))) // .or(() -> getAnnotationAttribute(Min.class, "value", Number.class)) // .or(() -> parsePropertyAnnotationValue(DecimalMin.class)) // .orElse(null); @@ -632,8 +635,9 @@ public class PropertyUtils { @Override public Number getMax() { - return Optional.ofNullable(RANGE_ANNOTATION) // - .flatMap(it -> getAnnotationAttribute(it, "max", Number.class)) // + return getAnnotationAttribute(Size.class, "max", Number.class) // + .or(() -> Optional.ofNullable(RANGE_ANNOTATION) + .flatMap(it -> getAnnotationAttribute(it, "max", Number.class))) // .or(() -> getAnnotationAttribute(Max.class, "value", Number.class)) // .or(() -> parsePropertyAnnotationValue(DecimalMax.class)) // .orElse(null); diff --git a/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java b/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java index ce07423c..62952d9b 100644 --- a/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java @@ -34,6 +34,7 @@ import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; import org.hibernate.validator.constraints.Range; import org.hibernate.validator.constraints.URL; @@ -187,7 +188,8 @@ class PropertyUtilsTest { InputTypes.of("url", HtmlInputType.URL), // InputTypes.of("stringUrl", HtmlInputType.URL), // InputTypes.of("email", HtmlInputType.EMAIL), // - InputTypes.of("ranged", HtmlInputType.RANGE)); + InputTypes.of("ranged", HtmlInputType.RANGE), + InputTypes.of("sized", HtmlInputType.RANGE)); InputPayloadMetadata metadata = PropertyUtils.getExposedProperties(InputTypeSample.class); @@ -225,6 +227,18 @@ class PropertyUtilsTest { }); } + @Test // #1920 + void exposesMinAndMaxFromJsr303AtSizeAnnotation() { + + InputPayloadMetadata metadata = PropertyUtils.getExposedProperties(Jsr303SamplePayload.class); + Optional property = metadata.stream().filter(it -> it.getName().equals("sized")).findFirst(); + + assertThat(property).hasValueSatisfying(it -> { + assertThat(it.getMin()).isEqualTo(41); + assertThat(it.getMax()).isEqualTo(4711); + }); + } + @Data @AllArgsConstructor @JsonIgnoreProperties({ "ignoreThisProperty" }) @@ -271,6 +285,7 @@ class PropertyUtilsTest { @Pattern(regexp = "\\w") String pattern; @NotBlank @Pattern(regexp = "\\w") String nonBlankPattern; TypeAnnotated annotated; + @Size(min = 41, max = 4711) int sized; } @Pattern(regexp = "regex") @@ -316,6 +331,8 @@ class PropertyUtilsTest { @URL String stringUrl; @Range int ranged; + + @Size int sized; } @Value