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 6588c906dd..61b3780038 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 @@ -68,10 +68,14 @@ import javax.validation.constraints.DecimalMin; import javax.validation.constraints.Max; import javax.validation.constraints.Min; +import javax.validation.constraints.Negative; +import javax.validation.constraints.NegativeOrZero; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; +import javax.validation.constraints.Positive; +import javax.validation.constraints.PositiveOrZero; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -1898,6 +1902,34 @@ protected boolean applyBeanValidatorAnnotations(Schema property, Annotation[] an modified = ValidationAnnotationsUtils.applyEmailConstraint(property, email) || modified; } } + if (annos.containsKey(JAVAX_POSITIVE)) { + Positive positive = (Positive) annos.get(JAVAX_POSITIVE); + boolean apply = checkGroupValidation(positive.groups(), invocationGroups, acceptNoGroups); + if (apply) { + modified = ValidationAnnotationsUtils.applyPositiveConstraint(property) || modified; + } + } + if (annos.containsKey(JAVAX_POSITIVE_OR_ZERO)) { + PositiveOrZero positiveOrZero = (PositiveOrZero) annos.get(JAVAX_POSITIVE_OR_ZERO); + boolean apply = checkGroupValidation(positiveOrZero.groups(), invocationGroups, acceptNoGroups); + if (apply) { + modified = ValidationAnnotationsUtils.applyPositiveOrZeroConstraint(property) || modified; + } + } + if (annos.containsKey(JAVAX_NEGATIVE)) { + Negative negative = (Negative) annos.get(JAVAX_NEGATIVE); + boolean apply = checkGroupValidation(negative.groups(), invocationGroups, acceptNoGroups); + if (apply) { + modified = ValidationAnnotationsUtils.applyNegativeConstraint(property) || modified; + } + } + if (annos.containsKey(JAVAX_NEGATIVE_OR_ZERO)) { + NegativeOrZero negativeOrZero = (NegativeOrZero) annos.get(JAVAX_NEGATIVE_OR_ZERO); + boolean apply = checkGroupValidation(negativeOrZero.groups(), invocationGroups, acceptNoGroups); + if (apply) { + modified = ValidationAnnotationsUtils.applyNegativeOrZeroConstraint(property) || modified; + } + } if (validatorProcessor != null && validatorProcessor.getMode().equals(ValidatorProcessor.MODE.AFTER)) { modified = validatorProcessor.applyBeanValidatorAnnotations(property, annotations, parent, applyNotNullAnnotations) || modified; } @@ -1961,6 +1993,18 @@ protected boolean applyBeanValidatorAnnotationsNoGroups(Schema property, Annotat Email pattern = (Email) annos.get(JAVAX_EMAIL); modified = ValidationAnnotationsUtils.applyEmailConstraint(property, pattern) || modified; } + if (annos.containsKey(JAVAX_POSITIVE)) { + modified = ValidationAnnotationsUtils.applyPositiveConstraint(property) || modified; + } + if (annos.containsKey(JAVAX_POSITIVE_OR_ZERO)) { + modified = ValidationAnnotationsUtils.applyPositiveOrZeroConstraint(property) || modified; + } + if (annos.containsKey(JAVAX_NEGATIVE)) { + modified = ValidationAnnotationsUtils.applyNegativeConstraint(property) || modified; + } + if (annos.containsKey(JAVAX_NEGATIVE_OR_ZERO)) { + modified = ValidationAnnotationsUtils.applyNegativeOrZeroConstraint(property) || modified; + } return modified; } diff --git a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ValidationAnnotationsUtils.java b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ValidationAnnotationsUtils.java index 3c9aad2c6e..e8e69da017 100644 --- a/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ValidationAnnotationsUtils.java +++ b/modules/swagger-core/src/main/java/io/swagger/v3/core/util/ValidationAnnotationsUtils.java @@ -19,6 +19,10 @@ public class ValidationAnnotationsUtils { public static final String JAVAX_DECIMAL_MAX = "javax.validation.constraints.DecimalMax"; public static final String JAVAX_PATTERN = "javax.validation.constraints.Pattern"; public static final String JAVAX_EMAIL = "javax.validation.constraints.Email"; + public static final String JAVAX_POSITIVE = "javax.validation.constraints.Positive"; + public static final String JAVAX_POSITIVE_OR_ZERO = "javax.validation.constraints.PositiveOrZero"; + public static final String JAVAX_NEGATIVE = "javax.validation.constraints.Negative"; + public static final String JAVAX_NEGATIVE_OR_ZERO = "javax.validation.constraints.NegativeOrZero"; private static final String SCHEMA_EMAIL_FORMAT_NAME = "email"; @@ -177,4 +181,38 @@ public static boolean applyEmailConstraint(Schema schema, Email annotation) { return false; } + public static boolean applyPositiveConstraint(Schema schema) { + if (isNumberSchema(schema)) { + schema.setMinimum(BigDecimal.ZERO); + schema.setExclusiveMinimum(true); + return true; + } + return false; + } + + public static boolean applyPositiveOrZeroConstraint(Schema schema) { + if (isNumberSchema(schema)) { + schema.setMinimum(BigDecimal.ZERO); + return true; + } + return false; + } + + public static boolean applyNegativeConstraint(Schema schema) { + if (isNumberSchema(schema)) { + schema.setMaximum(BigDecimal.ZERO); + schema.setExclusiveMaximum(true); + return true; + } + return false; + } + + public static boolean applyNegativeOrZeroConstraint(Schema schema) { + if (isNumberSchema(schema)) { + schema.setMaximum(BigDecimal.ZERO); + return true; + } + return false; + } + } diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/BeanValidationsModel.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/BeanValidationsModel.java index 9ef04c0921..4d375fa2a3 100644 --- a/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/BeanValidationsModel.java +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/BeanValidationsModel.java @@ -6,9 +6,14 @@ import javax.validation.constraints.Email; import javax.validation.constraints.Max; import javax.validation.constraints.Min; +import javax.validation.constraints.Negative; +import javax.validation.constraints.NegativeOrZero; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; +import javax.validation.constraints.Positive; +import javax.validation.constraints.PositiveOrZero; import javax.validation.constraints.Size; +import java.math.BigDecimal; import java.util.List; import java.util.Optional; @@ -40,6 +45,18 @@ public class BeanValidationsModel { protected Integer birthYear; + @Positive + protected BigDecimal positiveAmount; + + @PositiveOrZero + protected BigDecimal positiveOrZeroAmount; + + @Negative + protected BigDecimal negativeAmount; + + @NegativeOrZero + protected BigDecimal negativeOrZeroAmount; + @Size(min = 2, max = 10) private List<@Size(min = 3, max = 4) String> items; @@ -117,6 +134,38 @@ public void setBirthYear(Integer birthYear) { this.birthYear = birthYear; } + public BigDecimal getPositiveAmount() { + return positiveAmount; + } + + public void setPositiveAmount(BigDecimal positiveAmount) { + this.positiveAmount = positiveAmount; + } + + public BigDecimal getPositiveOrZeroAmount() { + return positiveOrZeroAmount; + } + + public void setPositiveOrZeroAmount(BigDecimal positiveOrZeroAmount) { + this.positiveOrZeroAmount = positiveOrZeroAmount; + } + + public BigDecimal getNegativeAmount() { + return negativeAmount; + } + + public void setNegativeAmount(BigDecimal negativeAmount) { + this.negativeAmount = negativeAmount; + } + + public BigDecimal getNegativeOrZeroAmount() { + return negativeOrZeroAmount; + } + + public void setNegativeOrZeroAmount(BigDecimal negativeOrZeroAmount) { + this.negativeOrZeroAmount = negativeOrZeroAmount; + } + public List getItems() { return items; } diff --git a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/BeanValidatorTest.java b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/BeanValidatorTest.java index b6bc728286..bb89694dca 100644 --- a/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/BeanValidatorTest.java +++ b/modules/swagger-core/src/test/java/io/swagger/v3/core/resolving/BeanValidatorTest.java @@ -56,5 +56,19 @@ public void readBeanValidatorTest() { final StringSchema optionalValue = (StringSchema) properties.get("optionalValue"); assertEquals((int) optionalValue.getMinLength(), 1); assertEquals((int) optionalValue.getMaxLength(), 10); + + final NumberSchema positiveAmount = (NumberSchema) properties.get("positiveAmount"); + assertEquals(positiveAmount.getMinimum(), BigDecimal.ZERO); + assertTrue(positiveAmount.getExclusiveMinimum()); + + final NumberSchema positiveOrZeroAmount = (NumberSchema) properties.get("positiveOrZeroAmount"); + assertEquals(positiveOrZeroAmount.getMinimum(), BigDecimal.ZERO); + + final NumberSchema negativeAmount = (NumberSchema) properties.get("negativeAmount"); + assertEquals(negativeAmount.getMaximum(), BigDecimal.ZERO); + assertTrue(negativeAmount.getExclusiveMaximum()); + + final NumberSchema negativeOrZeroAmount = (NumberSchema) properties.get("negativeOrZeroAmount"); + assertEquals(negativeOrZeroAmount.getMaximum(), BigDecimal.ZERO); } }