From 3a8bfa7aa7038478c0f3a552e162ba0e681f04c1 Mon Sep 17 00:00:00 2001 From: jfiala Date: Sat, 9 Jul 2016 18:47:53 +0200 Subject: [PATCH 1/7] add bean-validation support for params in WADLGenerator --- .../cxf/jaxrs/model/wadl/WadlGenerator.java | 89 ++++++++++++++++++- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java index 17b745f5c5b..18c1bd10207 100644 --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java @@ -48,7 +48,12 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; +import java.util.regex.Pattern; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import javax.ws.rs.BeanParam; import javax.ws.rs.DefaultValue; import javax.ws.rs.Encoded; @@ -959,16 +964,87 @@ protected void doWriteParam(OperationResourceInfo ori, } sb.append(" type=\"").append(value).append("\""); } + + StringBuffer beanValidationBuffer = checkForBeanValidationAnnotations(ori, sb, paramName, anns); + if (type.isEnum()) { sb.append(">"); handleDocs(anns, sb, DocTarget.PARAM, true, isJson); setEnumOptions(sb, type); sb.append(""); } else { - addDocsAndCloseElement(ori, pm.getIndex(), sb, anns, "param", DocTarget.PARAM, true, isJson); + + addDocsAndCloseElement(ori, pm.getIndex(), sb, anns, "param", DocTarget.PARAM, true, isJson, + beanValidationBuffer); + } + } + + private void addBeanValidationAnnotationsDocs(StringBuilder sb, StringBuffer beanValidationBuffer) { + // add docs if bean-validations are present for information + if (beanValidationBuffer != null && beanValidationBuffer.length() > 0) { + sb.append(""); + sb.append(beanValidationBuffer); + sb.append(""); } } + private StringBuffer checkForBeanValidationAnnotations(OperationResourceInfo ori, StringBuilder sb, + String paramName, Annotation[] anns) { + // TODO JF: Auswertung der Parameter!! + NotNull notNull = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.NotNull.class); + if (notNull != null) { + // parameter is required + sb.append(" minOccurs=\"1\""); + } + + StringBuffer beanValidationBuffer = new StringBuffer(); + + Size size = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.Size.class); + if (size != null) { + // TODO: we would have to add a simpleType to the XSD with restriction minLength/maxLength + // + // + // + // + // + beanValidationBuffer.append(" minLength: " + size.min()); + beanValidationBuffer.append(" maxLength: " + size.max()); + } + + Min min = AnnotationUtils.getAnnotation(anns, Min.class); + if (min != null) { + // TODO: we would have to add a simpleType to the XSD with minimum + beanValidationBuffer.append(" minimum: " + min.value()); + } + + Max max = AnnotationUtils.getAnnotation(anns, Max.class); + if (max != null) { + // TODO: we would have to add a simpleType to the XSD with minimum + beanValidationBuffer.append(" maximum: " + max.value()); + } + + Pattern pattern = AnnotationUtils.getAnnotation(anns, Pattern.class); + if (pattern != null) { + // TODO: we would have to add a simpleType to the XSD with restriction pattern + // + + beanValidationBuffer.append(" pattern: " + pattern.pattern()); + } + + + // TODO: ask if Swagger annotation support is welcome? + // ApiParam apiParam = AnnotationUtils.getAnnotation(anns, ApiParam.class); + // also have to check for @Description, see below + + // TODO debug output + System.out.println("*** param: " + ori.getAnnotatedMethod().getName() + " " + paramName); + System.out.println("*** anns: " + anns.length); + for (Annotation annotation : anns) { + System.out.println("*** type: " + annotation.annotationType()); + } + return beanValidationBuffer; + } + private void setEnumOptions(StringBuilder sb, Class enumClass) { try { Method m = enumClass.getMethod("values", new Class[] {}); @@ -991,10 +1067,12 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, String elementName, String category, boolean allowDefault, - boolean isJson) { + boolean isJson, + StringBuffer beanValidationBuffer) { //CHECKSTYLE:ON boolean docAnnAvailable = isDocAvailable(anns); - if (docAnnAvailable || (ori != null && !docProviders.isEmpty())) { + if (docAnnAvailable || (ori != null && !docProviders.isEmpty()) + || (beanValidationBuffer != null && beanValidationBuffer.length() > 0)) { sb.append(">"); if (docAnnAvailable) { handleDocs(anns, sb, category, allowDefault, isJson); @@ -1003,6 +1081,9 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, } else if (DocTarget.PARAM.equals(category)) { handleOperParamJavaDocs(ori, paramIndex, sb); } + + addBeanValidationAnnotationsDocs(sb, beanValidationBuffer); + sb.append(""); } else { sb.append("/>"); @@ -1086,7 +1167,7 @@ protected void handleRepresentation(StringBuilder sb, Set> jaxbTypes, getBodyAnnotations(ori, inbound)); } addDocsAndCloseElement(ori, inParamIndex, sb, anns, "representation", - docCategory, allowDefault, isJson); + docCategory, allowDefault, isJson, null); } } From 6748812e9d4841fe7a1bb64e437ca089f7a12004 Mon Sep 17 00:00:00 2001 From: jfiala Date: Sat, 9 Jul 2016 19:00:00 +0200 Subject: [PATCH 2/7] added addDocumentation helper method --- .../cxf/jaxrs/model/wadl/WadlGenerator.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java index 18c1bd10207..ca7c3c963b7 100644 --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java @@ -138,6 +138,9 @@ import org.apache.ws.commons.schema.XmlSchema; import org.apache.ws.commons.schema.constants.Constants; + +import io.swagger.annotations.ApiParam; + public class WadlGenerator implements ContainerRequestFilter { public static final String WADL_QUERY = "_wadl"; @@ -982,9 +985,7 @@ protected void doWriteParam(OperationResourceInfo ori, private void addBeanValidationAnnotationsDocs(StringBuilder sb, StringBuffer beanValidationBuffer) { // add docs if bean-validations are present for information if (beanValidationBuffer != null && beanValidationBuffer.length() > 0) { - sb.append(""); - sb.append(beanValidationBuffer); - sb.append(""); + addDocumentation(sb, beanValidationBuffer.toString()); } } @@ -1031,11 +1032,6 @@ private StringBuffer checkForBeanValidationAnnotations(OperationResourceInfo ori beanValidationBuffer.append(" pattern: " + pattern.pattern()); } - - // TODO: ask if Swagger annotation support is welcome? - // ApiParam apiParam = AnnotationUtils.getAnnotation(anns, ApiParam.class); - // also have to check for @Description, see below - // TODO debug output System.out.println("*** param: " + ori.getAnnotatedMethod().getName() + " " + paramName); System.out.println("*** anns: " + anns.length); @@ -1084,11 +1080,21 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, addBeanValidationAnnotationsDocs(sb, beanValidationBuffer); + ApiParam apiParam = AnnotationUtils.getAnnotation(anns, ApiParam.class); + if (apiParam != null && apiParam.value() != null) { + addDocumentation(sb, apiParam.value()); + } + sb.append(""); + } else { sb.append("/>"); } } + + private void addDocumentation(StringBuilder sb, String doc) { + sb.append("" + doc + ""); + } private boolean isDocAvailable(Annotation[] anns) { return AnnotationUtils.getAnnotation(anns, Description.class) != null From b4704dcf71de5b79752752dbc24260e53c8e5f50 Mon Sep 17 00:00:00 2001 From: jfiala Date: Sat, 9 Jul 2016 19:12:31 +0200 Subject: [PATCH 3/7] add Swagger @ApiParam annotation support --- .../apache/cxf/jaxrs/model/wadl/WadlGenerator.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java index ca7c3c963b7..543193047d0 100644 --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java @@ -1067,8 +1067,16 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, StringBuffer beanValidationBuffer) { //CHECKSTYLE:ON boolean docAnnAvailable = isDocAvailable(anns); + + boolean apiParamDocsAvailable = false; + ApiParam apiParam = AnnotationUtils.getAnnotation(anns, ApiParam.class); + if (apiParam != null && apiParam.value() != null) { + apiParamDocsAvailable = true; + } + if (docAnnAvailable || (ori != null && !docProviders.isEmpty()) - || (beanValidationBuffer != null && beanValidationBuffer.length() > 0)) { + || (beanValidationBuffer != null && beanValidationBuffer.length() > 0) + || apiParamDocsAvailable) { sb.append(">"); if (docAnnAvailable) { handleDocs(anns, sb, category, allowDefault, isJson); @@ -1080,8 +1088,7 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, addBeanValidationAnnotationsDocs(sb, beanValidationBuffer); - ApiParam apiParam = AnnotationUtils.getAnnotation(anns, ApiParam.class); - if (apiParam != null && apiParam.value() != null) { + if (apiParamDocsAvailable) { addDocumentation(sb, apiParam.value()); } From ffcfd37a5a9357edbb59d68700240c5de249d647 Mon Sep 17 00:00:00 2001 From: jfiala Date: Sat, 9 Jul 2016 20:52:40 +0200 Subject: [PATCH 4/7] added inline restrictions --- .../cxf/jaxrs/model/wadl/WadlGenerator.java | 130 ++++++++++++------ 1 file changed, 85 insertions(+), 45 deletions(-) diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java index 543193047d0..51a70cd5378 100644 --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java @@ -961,14 +961,23 @@ protected void doWriteParam(OperationResourceInfo ori, value = "xs:anyType"; } } + + checkForBeanValidationAnnotations(ori, sb, paramName, anns); + + + boolean stringRestrictionPresent = checkForBeanValidationAnnotationsForString(anns); + boolean numericRestrictionPresent = checkForBeanValidationAnnotationsForInteger(anns); + if (value != null) { if (isJson) { value = value.substring(3); } - sb.append(" type=\"").append(value).append("\""); + if (!stringRestrictionPresent && !numericRestrictionPresent) { + sb.append(" type=\"").append(value).append("\""); + } + } - StringBuffer beanValidationBuffer = checkForBeanValidationAnnotations(ori, sb, paramName, anns); if (type.isEnum()) { sb.append(">"); @@ -978,67 +987,59 @@ protected void doWriteParam(OperationResourceInfo ori, } else { addDocsAndCloseElement(ori, pm.getIndex(), sb, anns, "param", DocTarget.PARAM, true, isJson, - beanValidationBuffer); + stringRestrictionPresent, numericRestrictionPresent, value); } } - private void addBeanValidationAnnotationsDocs(StringBuilder sb, StringBuffer beanValidationBuffer) { - // add docs if bean-validations are present for information - if (beanValidationBuffer != null && beanValidationBuffer.length() > 0) { - addDocumentation(sb, beanValidationBuffer.toString()); - } - } - private StringBuffer checkForBeanValidationAnnotations(OperationResourceInfo ori, StringBuilder sb, + private void checkForBeanValidationAnnotations(OperationResourceInfo ori, StringBuilder sb, String paramName, Annotation[] anns) { - // TODO JF: Auswertung der Parameter!! - NotNull notNull = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.NotNull.class); + + NotNull notNull = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.NotNull.class); if (notNull != null) { // parameter is required sb.append(" minOccurs=\"1\""); } - StringBuffer beanValidationBuffer = new StringBuffer(); + // TODO debug output +// System.out.println("*** param: " + ori.getAnnotatedMethod().getName() + " " + paramName); +// System.out.println("*** anns: " + anns.length); +// for (Annotation annotation : anns) { +// System.out.println("*** type: " + annotation.annotationType()); +// } + } + + private boolean checkForBeanValidationAnnotationsForString(Annotation[] anns) { + boolean present = false; Size size = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.Size.class); if (size != null) { - // TODO: we would have to add a simpleType to the XSD with restriction minLength/maxLength - // - // - // - // - // - beanValidationBuffer.append(" minLength: " + size.min()); - beanValidationBuffer.append(" maxLength: " + size.max()); + present = true; + } + + Pattern pattern = AnnotationUtils.getAnnotation(anns, Pattern.class); + if (pattern != null) { + present = true; } + return present; + } + + private boolean checkForBeanValidationAnnotationsForInteger(Annotation[] anns) { + boolean present = false; + Min min = AnnotationUtils.getAnnotation(anns, Min.class); if (min != null) { - // TODO: we would have to add a simpleType to the XSD with minimum - beanValidationBuffer.append(" minimum: " + min.value()); + present = true; } Max max = AnnotationUtils.getAnnotation(anns, Max.class); if (max != null) { - // TODO: we would have to add a simpleType to the XSD with minimum - beanValidationBuffer.append(" maximum: " + max.value()); + present = true; } - Pattern pattern = AnnotationUtils.getAnnotation(anns, Pattern.class); - if (pattern != null) { - // TODO: we would have to add a simpleType to the XSD with restriction pattern - // - - beanValidationBuffer.append(" pattern: " + pattern.pattern()); - } + return present; - // TODO debug output - System.out.println("*** param: " + ori.getAnnotatedMethod().getName() + " " + paramName); - System.out.println("*** anns: " + anns.length); - for (Annotation annotation : anns) { - System.out.println("*** type: " + annotation.annotationType()); - } - return beanValidationBuffer; } private void setEnumOptions(StringBuilder sb, Class enumClass) { @@ -1064,7 +1065,9 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, String category, boolean allowDefault, boolean isJson, - StringBuffer beanValidationBuffer) { + boolean stringRestrictionPresent, + boolean numericRestrictionPresent, + String type) { //CHECKSTYLE:ON boolean docAnnAvailable = isDocAvailable(anns); @@ -1075,8 +1078,9 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, } if (docAnnAvailable || (ori != null && !docProviders.isEmpty()) - || (beanValidationBuffer != null && beanValidationBuffer.length() > 0) - || apiParamDocsAvailable) { + || apiParamDocsAvailable + || stringRestrictionPresent + || numericRestrictionPresent) { sb.append(">"); if (docAnnAvailable) { handleDocs(anns, sb, category, allowDefault, isJson); @@ -1086,12 +1090,48 @@ private void addDocsAndCloseElement(OperationResourceInfo ori, handleOperParamJavaDocs(ori, paramIndex, sb); } - addBeanValidationAnnotationsDocs(sb, beanValidationBuffer); - if (apiParamDocsAvailable) { addDocumentation(sb, apiParam.value()); } + if (stringRestrictionPresent) { + sb.append(""); + sb.append(" "); + + Size size = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.Size.class); + if (size != null) { + sb.append(" "); + sb.append(" "); + } + + javax.validation.constraints.Pattern pattern = + AnnotationUtils.getAnnotation(anns, javax.validation.constraints.Pattern.class); + if (pattern != null) { + sb.append(" "); + } + + sb.append(" "); + sb.append(""); + } + + if (numericRestrictionPresent) { + sb.append(""); + sb.append(" "); + + Min min = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.Min.class); + if (min != null) { + sb.append(" "); + } + + Max max = AnnotationUtils.getAnnotation(anns, javax.validation.constraints.Max.class); + if (max != null) { + sb.append(" "); + } + + sb.append(" "); + sb.append(""); + } + sb.append(""); } else { @@ -1180,7 +1220,7 @@ protected void handleRepresentation(StringBuilder sb, Set> jaxbTypes, getBodyAnnotations(ori, inbound)); } addDocsAndCloseElement(ori, inParamIndex, sb, anns, "representation", - docCategory, allowDefault, isJson, null); + docCategory, allowDefault, isJson, false, false, null); } } From 391db1bc8c2b32ba270aab429358a9b05d72e71c Mon Sep 17 00:00:00 2001 From: jfiala Date: Sun, 10 Jul 2016 20:39:19 +0200 Subject: [PATCH 5/7] implement bean-validation support @NotNull --- tools/wadlto/jaxrs/pom.xml | 4 ++++ .../apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/tools/wadlto/jaxrs/pom.xml b/tools/wadlto/jaxrs/pom.xml index 4bf98e08100..cc45d54313e 100644 --- a/tools/wadlto/jaxrs/pom.xml +++ b/tools/wadlto/jaxrs/pom.xml @@ -61,5 +61,9 @@ 0.6.4 test + + javax.validation + validation-api + diff --git a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java index f07df3b3ce8..77ae5edff69 100644 --- a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java +++ b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java @@ -46,6 +46,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import javax.validation.constraints.NotNull; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; @@ -1265,6 +1266,15 @@ private void writeRequestTypes(Element requestEl, writeAnnotation(sbCode, imports, DefaultValue.class, defaultVal, false, false); sbCode.append(" "); } + + // Add BeanValidation annotations + // @NotNull + if ("true".equals(required)) { + writeAnnotation(sbCode, imports, NotNull.class, null, false, false); + sbCode.append(" "); + } + + } boolean isRepeating = isRepeatingParam(paramEl); String type = enumCreated ? getTypicalClassName(name) From 8ec4c672beada5a8fbeab507bf5f0dd76f504087 Mon Sep 17 00:00:00 2001 From: Johannes Fiala Date: Sun, 11 Sep 2016 10:54:35 +0200 Subject: [PATCH 6/7] add beanvalidation annotations based on simpletype restrictions --- .../tools/wadlto/jaxrs/SourceGenerator.java | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java index 77ae5edff69..4f3176ba93d 100644 --- a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java +++ b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java @@ -47,6 +47,8 @@ import java.util.logging.Logger; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; @@ -79,7 +81,7 @@ import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; - +import org.w3c.dom.NodeList; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -1274,6 +1276,7 @@ private void writeRequestTypes(Element requestEl, sbCode.append(" "); } + checkForBeanValidationsBasedOnSimpleType(sbCode, imports, paramEl); } boolean isRepeating = isRepeatingParam(paramEl); @@ -1354,6 +1357,89 @@ private void writeRequestTypes(Element requestEl, .append(AsyncResponse.class.getSimpleName()).append(" ").append("async"); } } + + private void checkForBeanValidationsBasedOnSimpleType(StringBuilder sbCode, Set imports, Element paramEl) { + NodeList children = paramEl.getChildNodes(); + for (int nodeLevel1Index = 0; nodeLevel1Index < children.getLength(); nodeLevel1Index++) { + Node paramNodeLevel1 = children.item(nodeLevel1Index); + + if ("xs:simpleType".equals(paramNodeLevel1.getNodeName())) { + NodeList children2 = paramNodeLevel1.getChildNodes(); + for (int nodeLevel2Index = 0; nodeLevel2Index < children2.getLength(); nodeLevel2Index++) { + Node paramNodeLevel2 = children2.item(nodeLevel2Index); + + if ("xs:restriction".equals(paramNodeLevel2.getNodeName())) { + NodeList children3 = paramNodeLevel2.getChildNodes(); + + addSimpleTypeBeanValidationAnnotations(sbCode, imports, children3); + } + + + + + } + } + + + + } + } + + private void addSimpleTypeBeanValidationAnnotations(StringBuilder sbCode, Set imports, NodeList children3) { + String minLength = null; + String maxLength = null; + String regexp = null; + + for (int nodeLevel3Index = 0; nodeLevel3Index < children3.getLength(); nodeLevel3Index++) { + Node paramNodeLevel3 = children3.item(nodeLevel3Index); + + if ("xs:minLength".equals(paramNodeLevel3.getNodeName())) { + minLength = getNodeElementAttribute(paramNodeLevel3); + } + + if ("xs:maxLength".equals(paramNodeLevel3.getNodeName())) { + maxLength = getNodeElementAttribute(paramNodeLevel3); + } + + if ("xs:pattern".equals(paramNodeLevel3.getNodeName())) { + regexp = getNodeElementAttribute(paramNodeLevel3); + } + } + + if (minLength != null || maxLength != null) { + writeAnnotation(sbCode, imports, Size.class, null, false, false); + + sbCode.append("("); + if (minLength != null) { + LOG.info("minLength: " + minLength); + sbCode.append("min=" + minLength); + } + if (maxLength != null) { + LOG.info("maxLength: " + maxLength); + if (minLength != null) { + sbCode.append(","); + } + sbCode.append("max=" + maxLength); + } + sbCode.append(") "); + + } + + if (regexp != null) { + writeAnnotation(sbCode, imports, Pattern.class, null, false, false); + LOG.info("pattern.regexp: " + regexp); + sbCode.append("(regexp=\"" + regexp + "\") "); + } + } + + private String getNodeElementAttribute(Node node) { + String value = null; + if (node.getNodeType() == Node.ELEMENT_NODE) { + Element mynode3Elem = (Element)node; + value = mynode3Elem.getAttribute("value"); + } + return value; + } private boolean isRepeatingParam(Element paramEl) { return Boolean.valueOf(paramEl.getAttribute("repeating")); From 14482cfde4d6bf48f8b300f6e2123dd721f7fb62 Mon Sep 17 00:00:00 2001 From: jfiala Date: Sat, 17 Sep 2016 15:59:18 +0200 Subject: [PATCH 7/7] add detection of beanvalidation for schema type references --- .../tools/wadlto/jaxrs/SourceGenerator.java | 118 +++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java index 4f3176ba93d..840a944b656 100644 --- a/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java +++ b/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/SourceGenerator.java @@ -111,6 +111,14 @@ import org.apache.cxf.service.model.SchemaInfo; import org.apache.cxf.staxutils.StaxUtils; import org.apache.ws.commons.schema.XmlSchema; +import org.apache.ws.commons.schema.XmlSchemaFacet; +import org.apache.ws.commons.schema.XmlSchemaMaxLengthFacet; +import org.apache.ws.commons.schema.XmlSchemaMinLengthFacet; +import org.apache.ws.commons.schema.XmlSchemaPatternFacet; +import org.apache.ws.commons.schema.XmlSchemaSimpleType; +import org.apache.ws.commons.schema.XmlSchemaSimpleTypeContent; +import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction; +import org.apache.ws.commons.schema.XmlSchemaType; import org.apache.ws.commons.schema.constants.Constants; public class SourceGenerator { @@ -224,6 +232,9 @@ public class SourceGenerator { private boolean supportMultipleRepsWithElements; private boolean validateWadl; private SchemaCollection schemaCollection = new SchemaCollection(); + + private Map wadlPrefixMap = new HashMap(); + private String encoding; private boolean createJavaDocs; @@ -293,6 +304,9 @@ private String getFileSep() { public void generateSource(String wadl, File srcDir, String codeType) { Application app = readWadl(wadl, wadlPath); + // scan for prefixes used in WADL + wadlPrefixMap = createWadlPrefixMap(app); + Set typeClassNames = new HashSet(); GrammarInfo gInfo = generateSchemaCodeAndInfo(app, typeClassNames, srcDir); if (!CODE_TYPE_GRAMMAR.equals(codeType)) { @@ -1276,7 +1290,7 @@ private void writeRequestTypes(Element requestEl, sbCode.append(" "); } - checkForBeanValidationsBasedOnSimpleType(sbCode, imports, paramEl); + checkForBeanValidations(sbCode, imports, paramEl); } boolean isRepeating = isRepeatingParam(paramEl); @@ -1358,7 +1372,74 @@ private void writeRequestTypes(Element requestEl, } } - private void checkForBeanValidationsBasedOnSimpleType(StringBuilder sbCode, Set imports, Element paramEl) { + private void checkForBeanValidations(StringBuilder sbCode, Set imports, Element paramEl) { + LOG.fine("checking for BeanValidations for parameter " + paramEl.getAttribute("name")); + + checkForBeanValidationsBasedOnInlineSimpleType(sbCode, imports, paramEl); + + checkForBeanValidationBasedOnSchemaType(sbCode, imports, paramEl); + + } + + private void checkForBeanValidationBasedOnSchemaType(StringBuilder sbCode, Set imports, + Element paramEl) { + // type reference to schema + String type = paramEl.getAttribute("type"); + + if (type != null && type.indexOf(":") >= 0) { + LOG.fine("checking bean validation for type: " + type); + String typeWithoutPrefix = org.apache.commons.lang.StringUtils.substringAfter(type, ":"); + String prefix = org.apache.commons.lang.StringUtils.substringBefore(type, ":"); + LOG.fine("prefix: " + prefix); + + String namespaceURI = wadlPrefixMap.get(prefix); + QName schemaTypeQName = new QName(namespaceURI, typeWithoutPrefix); + LOG.fine("schemaTypeQName: " + schemaTypeQName); + XmlSchemaType schemaType = schemaCollection.getTypeByQName(schemaTypeQName); + + if (schemaType instanceof XmlSchemaSimpleType) { + LOG.fine("detected simple type"); + XmlSchemaSimpleType schemaSimpleType = (XmlSchemaSimpleType) schemaType; + + XmlSchemaSimpleTypeContent xmlSchemaContent = schemaSimpleType.getContent(); + if (xmlSchemaContent instanceof XmlSchemaSimpleTypeRestriction) { + XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction) xmlSchemaContent; + QName baseTypeName = restriction.getBaseTypeName(); + + addBeanValidationForFacets(sbCode, imports, restriction, baseTypeName); + + } + + } + + } + } + + private void addBeanValidationForFacets(StringBuilder sbCode, Set imports, + XmlSchemaSimpleTypeRestriction restriction, QName baseTypeName) { + if ("string".equals(baseTypeName.getLocalPart())) { + LOG.fine("detected simple type string"); + addBeanValidationForStringFacets(sbCode, imports, restriction); + } + } + + private Map createWadlPrefixMap(Application app) { + // since NamespaceContext length is 0 here, check for prefixes + // in + // WADL application element + Map result = new HashMap(); + NamedNodeMap map = app.getAppElement().getAttributes(); + for (int i = 0; i < map.getLength(); i++) { + Node mynode = map.item(i); + String wadlDeclaredPrefix = mynode.getLocalName(); + String wadlDeclaredNamespaceURI = mynode.getNodeValue(); + result.put(wadlDeclaredPrefix, wadlDeclaredNamespaceURI); + } + return result; + } + + private void checkForBeanValidationsBasedOnInlineSimpleType(StringBuilder sbCode, Set imports, + Element paramEl) { NodeList children = paramEl.getChildNodes(); for (int nodeLevel1Index = 0; nodeLevel1Index < children.getLength(); nodeLevel1Index++) { Node paramNodeLevel1 = children.item(nodeLevel1Index); @@ -1385,6 +1466,34 @@ private void checkForBeanValidationsBasedOnSimpleType(StringBuilder sbCode, Set< } } + private void addBeanValidationForStringFacets(StringBuilder sbCode, Set imports, + XmlSchemaSimpleTypeRestriction restriction) { + String minLength = null; + String maxLength = null; + String regexp = null; + + for (XmlSchemaFacet facet : restriction.getFacets()) { + + if (facet instanceof XmlSchemaMinLengthFacet) { + minLength = (String) facet.getValue(); + LOG.fine("detected minLength: " + minLength); + } + + if (facet instanceof XmlSchemaMaxLengthFacet) { + maxLength = (String) facet.getValue(); + LOG.fine("detected maxLength: " + maxLength); + } + + if (facet instanceof XmlSchemaPatternFacet) { + regexp = (String) facet.getValue(); + LOG.fine("detected regexp: " + regexp); + } + } + + writeBeanValidationAnnotations(sbCode, imports, minLength, maxLength, regexp); + } + + private void addSimpleTypeBeanValidationAnnotations(StringBuilder sbCode, Set imports, NodeList children3) { String minLength = null; String maxLength = null; @@ -1406,6 +1515,11 @@ private void addSimpleTypeBeanValidationAnnotations(StringBuilder sbCode, Set imports, String minLength, + String maxLength, String regexp) { if (minLength != null || maxLength != null) { writeAnnotation(sbCode, imports, Size.class, null, false, false);