Repository: joelittlejohn/jsonschema2pojo (language: java)

Issue:
Add support for more JSR-303 validation(@Email) for {"format":"email"}



Discussion / hints:
Happy to accept a pull request for this :+1: 

Fix patch:
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java
index f2095b95a..9bb0ecb72 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java
@@ -16,7 +16,6 @@
 
 package org.jsonschema2pojo.rules;
 
-import org.apache.commons.lang.StringUtils;
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.JsonPointerUtils;
 import org.jsonschema2pojo.Schema;
@@ -31,6 +30,7 @@
 import com.sun.codemodel.JMod;
 import com.sun.codemodel.JType;
 import com.sun.codemodel.JVar;
+import org.apache.commons.lang.StringUtils;
 
 /**
  * Applies the schema rules that represent a property definition.
@@ -201,6 +201,12 @@ private void formatAnnotation(JFieldVar field, JDefinedClass clazz, JsonNode nod
             ruleFactory.getAnnotator().dateField(field, clazz, node);
         } else if ("time".equalsIgnoreCase(format)) {
             ruleFactory.getAnnotator().timeField(field, clazz, node);
+        } else if ("email".equalsIgnoreCase(format) && ruleFactory.getGenerationConfig().isIncludeJsr303Annotations()) {
+            if (ruleFactory.getGenerationConfig().isUseJakartaValidation()) {
+                field.annotate(jakarta.validation.constraints.Email.class);
+            } else {
+                field.annotate(javax.validation.constraints.Email.class);
+            }
         }
     }
 
diff --git a/pom.xml b/pom.xml
index 07a5a9591..7dae16b95 100644
--- a/pom.xml
+++ b/pom.xml
@@ -307,7 +307,7 @@
             <dependency>
                 <groupId>javax.validation</groupId>
                 <artifactId>validation-api</artifactId>
-                <version>1.1.0.Final</version>
+                <version>2.0.1.Final</version>
             </dependency>
             <dependency>
                 <groupId>jakarta.validation</groupId>
@@ -356,6 +356,12 @@
                 <artifactId>ant</artifactId>
                 <version>1.10.13</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.bval</groupId>
+                <artifactId>bval-jsr</artifactId>
+                <version>2.0.6</version>
+                <scope>test</scope>
+            </dependency>
             <dependency>
                 <groupId>org.apache.maven</groupId>
                 <artifactId>maven-plugin-api</artifactId>
@@ -386,7 +392,7 @@
             <dependency>
                 <groupId>org.hibernate.validator</groupId>
                 <artifactId>hibernate-validator</artifactId>
-                <version>7.0.1.Final</version>
+                <version>7.0.5.Final</version>
                 <scope>test</scope>
             </dependency>
             <dependency>


Test patch:
diff --git a/jsonschema2pojo-integration-tests/pom.xml b/jsonschema2pojo-integration-tests/pom.xml
index 39fad03f2..603b9ac01 100644
--- a/jsonschema2pojo-integration-tests/pom.xml
+++ b/jsonschema2pojo-integration-tests/pom.xml
@@ -154,9 +154,7 @@
         <!-- javax.validation implementation dependencies: start -->
         <dependency>
             <groupId>org.apache.bval</groupId>
-            <artifactId>bval-jsr303</artifactId>
-            <version>0.5</version>
-            <scope>test</scope>
+            <artifactId>bval-jsr</artifactId>
         </dependency>
         <dependency>
             <groupId>javax.validation</groupId>
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java
index 49fe40f10..bce32ce54 100644
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java
+++ b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/IncludeJsr303AnnotationsIT.java
@@ -21,6 +21,11 @@
 import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.*;
 import static org.junit.Assert.*;
 
+import org.jsonschema2pojo.integration.util.FileSearchMatcher;
+import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
+
+import jakarta.validation.Validation;
+import jakarta.validation.Validator;
 import java.beans.PropertyDescriptor;
 import java.io.File;
 import java.lang.reflect.InvocationTargetException;
@@ -32,19 +37,13 @@
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
-
-import org.apache.bval.jsr303.ApacheValidationProvider;
+import org.apache.bval.jsr.ApacheValidationProvider;
 import org.hamcrest.Matcher;
-import org.jsonschema2pojo.integration.util.FileSearchMatcher;
-import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import jakarta.validation.Validation;
-import jakarta.validation.Validator;
-
 @SuppressWarnings("rawtypes")
 @RunWith(Parameterized.class)
 public class IncludeJsr303AnnotationsIT {
@@ -182,6 +181,23 @@ public void jsr303SizeValidationIsAddedForSchemaRuleMinItemsAndMaxItems() throws
 
     }
 
+    @Test
+    public void jsr303EmailValidationIsAddedForFormatEmailSchemaRule() throws ClassNotFoundException {
+
+        ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/email.json", "com.example",
+                config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
+
+        Class generatedType = resultsClassLoader.loadClass("com.example.Email");
+
+        Object validInstance = createInstanceWithPropertyValue(generatedType, "email", "user@example.com");
+
+        assertNumberOfConstraintViolationsOn(validInstance, is(0));
+
+        Object invalidInstance = createInstanceWithPropertyValue(generatedType, "email", "aaa");
+
+        assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
+    }
+
     @Test
     public void jsr303PatternValidationIsAddedForSchemaRulePattern() throws ClassNotFoundException {
 
@@ -361,7 +377,7 @@ public void jsr303ValidAnnotationIsAddedForArrayWithRef() throws ClassNotFoundEx
 
     @SuppressWarnings("unchecked")
     @Test
-    public void jar303AnnotationsValidatedForAdditionalProperties() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    public void jsr303AnnotationsValidatedForAdditionalProperties() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validAdditionalProperties.json", "com.example",
                 config("includeJsr303Annotations", true, "useJakartaValidation", useJakartaValidation));
 
@@ -383,7 +399,8 @@ public void jar303AnnotationsValidatedForAdditionalProperties() throws ClassNotF
 
     private void assertNumberOfConstraintViolationsOn(Object instance, Matcher<Integer> matcher) {
         final Set<?> violationsForValidInstance = useJakartaValidation ? validator.validate(instance) : javaxValidator.validate(instance);
-        assertThat(violationsForValidInstance.size(), matcher);
+        final String validatorName = useJakartaValidation ? "jakarta/hibernate validator" : "javax/bval validator";
+        assertThat("Violations (" + validatorName + "): " + violationsForValidInstance.toString(), violationsForValidInstance.size(), matcher);
     }
 
     private static Object createInstanceWithPropertyValue(Class type, String propertyName, Object propertyValue) {
diff --git a/jsonschema2pojo-integration-tests/src/test/resources/schema/jsr303/email.json b/jsonschema2pojo-integration-tests/src/test/resources/schema/jsr303/email.json
new file mode 100644
index 000000000..b369d628a
--- /dev/null
+++ b/jsonschema2pojo-integration-tests/src/test/resources/schema/jsr303/email.json
@@ -0,0 +1,9 @@
+{
+  "type" : "object",
+  "properties" : {
+    "email" : {
+      "type" : "string",
+      "format": "email"
+    }
+  }
+}