[CXF-6695] Handling bean validation annotations for @BeanParam fields
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/b1ab9e91 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/b1ab9e91 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/b1ab9e91 Branch: refs/heads/3.0.x-fixes Commit: b1ab9e914193495b2301b5b1d85d7a47fc2cb81e Parents: ace4d32 Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Thu Dec 3 14:34:30 2015 +0100 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Thu Dec 3 14:34:30 2015 +0100 ---------------------------------------------------------------------- .../cxf/jaxrs/swagger/JaxRs2Extension.java | 89 +++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/b1ab9e91/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/JaxRs2Extension.java ---------------------------------------------------------------------- diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/JaxRs2Extension.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/JaxRs2Extension.java index 55054da..bba367f 100644 --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/JaxRs2Extension.java +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/JaxRs2Extension.java @@ -21,9 +21,18 @@ package org.apache.cxf.jaxrs.swagger; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; +import javax.validation.constraints.DecimalMax; +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; import javax.ws.rs.BeanParam; import javax.ws.rs.MatrixParam; @@ -38,6 +47,7 @@ import io.swagger.jaxrs.ext.AbstractSwaggerExtension; import io.swagger.jaxrs.ext.SwaggerExtension; import io.swagger.jaxrs.ext.SwaggerExtensions; import io.swagger.models.parameters.Parameter; +import io.swagger.models.properties.AbstractNumericProperty; import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.Property; import io.swagger.models.properties.RefProperty; @@ -115,6 +125,7 @@ public class JaxRs2Extension extends AbstractSwaggerExtension { // since downstream processors won't know how to introspect @BeanParam, process here for (Parameter param : extracted) { if (ParameterProcessor.applyAnnotations(null, param, paramType, paramAnnotations) != null) { + applyBeanValidatorAnnotations(param, paramAnnotations); parameters.add(param); } } @@ -130,11 +141,11 @@ public class JaxRs2Extension extends AbstractSwaggerExtension { return parameters; } - private Property createProperty(Type type) { + private Property createProperty(final Type type) { return enforcePrimitive(ModelConverters.getInstance().readAsProperty(type), 0); } - private Property enforcePrimitive(Property in, int level) { + private Property enforcePrimitive(final Property in, final int level) { if (in instanceof RefProperty) { return new StringProperty(); } @@ -148,4 +159,78 @@ public class JaxRs2Extension extends AbstractSwaggerExtension { } return in; } + + /** + * This is essentially a duplicate of {@link io.swagger.jackson.ModelResolver.applyBeanValidatorAnnotations}. + * + * @param property + * @param annotations + */ + private void applyBeanValidatorAnnotations(final Parameter property, final List<Annotation> annotations) { + Map<String, Annotation> annos = new HashMap<String, Annotation>(); + if (annotations != null) { + for (Annotation annotation : annotations) { + annos.put(annotation.annotationType().getName(), annotation); + } + } + if (annos.containsKey(NotNull.class.getName())) { + property.setRequired(true); + } + if (annos.containsKey(Min.class.getName()) && property instanceof AbstractNumericProperty) { + Min min = (Min) annos.get(Min.class.getName()); + AbstractNumericProperty ap = (AbstractNumericProperty) property; + ap.setMinimum(new Double(min.value())); + } + if (annos.containsKey(Max.class.getName()) && property instanceof AbstractNumericProperty) { + Max max = (Max) annos.get(Max.class.getName()); + AbstractNumericProperty ap = (AbstractNumericProperty) property; + ap.setMaximum(new Double(max.value())); + } + if (annos.containsKey(Size.class.getName())) { + Size size = (Size) annos.get(Size.class.getName()); + if (property instanceof AbstractNumericProperty) { + AbstractNumericProperty ap = (AbstractNumericProperty) property; + ap.setMinimum(new Double(size.min())); + ap.setMaximum(new Double(size.max())); + } else if (property instanceof StringProperty) { + StringProperty sp = (StringProperty) property; + sp.minLength(size.min()); + sp.maxLength(size.max()); + } else if (property instanceof ArrayProperty) { + ArrayProperty sp = (ArrayProperty) property; + sp.setMinItems(size.min()); + sp.setMaxItems(size.max()); + } + } + if (annos.containsKey(DecimalMin.class.getName())) { + DecimalMin min = (DecimalMin) annos.get(DecimalMin.class.getName()); + if (property instanceof AbstractNumericProperty) { + AbstractNumericProperty ap = (AbstractNumericProperty) property; + if (min.inclusive()) { + ap.setMinimum(new Double(min.value())); + } else { + ap.setExclusiveMinimum(!min.inclusive()); + } + } + } + if (annos.containsKey(DecimalMax.class.getName())) { + DecimalMax max = (DecimalMax) annos.get(DecimalMax.class.getName()); + if (property instanceof AbstractNumericProperty) { + AbstractNumericProperty ap = (AbstractNumericProperty) property; + if (max.inclusive()) { + ap.setMaximum(new Double(max.value())); + } else { + ap.setExclusiveMaximum(!max.inclusive()); + } + } + } + if (annos.containsKey(Pattern.class.getName())) { + Pattern pattern = (Pattern) annos.get(Pattern.class.getName()); + if (property instanceof StringProperty) { + StringProperty ap = (StringProperty) property; + ap.setPattern(pattern.regexp()); + } + } + } + }