diff --git a/beanvalidationdemo/beanvalidationdemo.iml b/beanvalidationdemo/beanvalidationdemo.iml
new file mode 100644
index 0000000..110df22
--- /dev/null
+++ b/beanvalidationdemo/beanvalidationdemo.iml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/beanvalidationdemo/pom.xml b/beanvalidationdemo/pom.xml
new file mode 100644
index 0000000..8200027
--- /dev/null
+++ b/beanvalidationdemo/pom.xml
@@ -0,0 +1,87 @@
+
+
+ 4.0.0
+ beanvalidationdemo
+ beanvalidationdemo
+
+
+ jeedemo
+ it.plague.jeedemo
+ 1.0-SNAPSHOT
+
+
+
+ UTF-8
+ it.plague.jeedemo.BeanValidationMain
+ 1.7
+ 1.7
+
+
+
+
+ org.hibernate
+ hibernate-validator
+
+
+ org.glassfish
+ javax.el
+
+
+ org.jboss.weld.se
+ weld-se-core
+
+
+ org.projectlombok
+ lombok
+
+
+ junit
+ junit
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.5.1
+
+ 1.7
+ 1.7
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 2.12.4
+
+
+ integration-test
+
+ integration-test
+ verify
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.2.1
+
+
+
+ java
+
+
+ it.plague.jeedemo.BeanValidationMain
+
+
+
+
+
+
+
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/Address.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/Address.java
new file mode 100644
index 0000000..c5ba402
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/Address.java
@@ -0,0 +1,32 @@
+package it.plague.jeedemo;
+
+import javax.validation.constraints.NotNull;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Address {
+
+ @NotNull
+ private String street1;
+ private String street2;
+ @NotNull
+ private String city;
+ private String state;
+ @NotNull
+ @ZipCode
+ private String zipCode;
+ private String coutry;
+
+ public Address(@NotNull String street1, @NotNull String city, String state,
+ @NotNull String zipCode, String coutry) {
+ this.street1 = street1;
+ this.city = city;
+ this.state = state;
+ this.zipCode = zipCode;
+ this.coutry = coutry;
+ }
+}
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/BeanValidationMain.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/BeanValidationMain.java
new file mode 100644
index 0000000..9dbf7d0
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/BeanValidationMain.java
@@ -0,0 +1,13 @@
+package it.plague.jeedemo;
+
+/**
+ * Hello world!
+ *
+ */
+public class BeanValidationMain
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/Customer.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/Customer.java
new file mode 100644
index 0000000..8aa40dd
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/Customer.java
@@ -0,0 +1,31 @@
+package it.plague.jeedemo;
+
+import java.util.Date;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Past;
+import javax.validation.constraints.Size;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Customer {
+
+ @NotNull
+ @Size(min = 2)
+ private String firstName;
+ private String lastName;
+ @Email
+ private String email;
+ private String phoneNumber;
+ @Past
+ private Date dateOfBirth;
+ private Address deliveryAddress;
+
+ public Customer(
+ @NotNull @Size(min = 2) String firstName, String lastName, String email) {
+ this(firstName, lastName, email, null, null, null);
+ }
+}
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/Email.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/Email.java
new file mode 100644
index 0000000..5cfd9dd
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/Email.java
@@ -0,0 +1,37 @@
+package it.plague.jeedemo;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+@Size(min = 7)
+@Pattern(regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\."
+ + "[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"
+ + "@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
+@ReportAsSingleViolation
+@Constraint(validatedBy = {})
+@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,
+ ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Email {
+
+ String message() default "{it.plague.jeedemo.Email.message}";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+ @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,
+ ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface List {
+
+ Email[] value();
+ }
+}
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/USA.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/USA.java
new file mode 100644
index 0000000..aa4a2b7
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/USA.java
@@ -0,0 +1,14 @@
+package it.plague.jeedemo;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.inject.Qualifier;
+
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
+public @interface USA {
+
+}
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCode.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCode.java
new file mode 100644
index 0000000..ebf3d03
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCode.java
@@ -0,0 +1,29 @@
+package it.plague.jeedemo;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Constraint(validatedBy = ZipCodeValidator.class)
+@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,
+ ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ZipCode {
+
+ String message() default "{it.plague.jeedemo.beanvalidation.ZipCode.message}";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+ @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,
+ ElementType.CONSTRUCTOR, ElementType.PARAMETER})
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface List {
+
+ ZipCode[] value();
+ }
+}
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCodeChecker.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCodeChecker.java
new file mode 100644
index 0000000..c72bbc1
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCodeChecker.java
@@ -0,0 +1,9 @@
+package it.plague.jeedemo;
+
+public class ZipCodeChecker {
+
+ public boolean isZipCodeValid(String value) {
+ // TODO it's not important for this example, here could you do anything do you want
+ return true;
+ }
+}
diff --git a/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCodeValidator.java b/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCodeValidator.java
new file mode 100644
index 0000000..199d0b3
--- /dev/null
+++ b/beanvalidationdemo/src/main/java/it/plague/jeedemo/ZipCodeValidator.java
@@ -0,0 +1,38 @@
+package it.plague.jeedemo;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.inject.Inject;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+public class ZipCodeValidator implements ConstraintValidator {
+
+ /**
+ * FIXME
+ * this attribute not work, because @Produce
+ * not defined
+ */
+ @Inject
+ @USA
+ private ZipCodeChecker checker;
+
+ private Pattern zipPattern = Pattern.compile("\\d{5}(-\\d{5})?");
+
+ @Override
+ public void initialize(ZipCode zipCode) {
+
+ }
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ if (value == null) {
+ return true;
+ }
+ Matcher m = zipPattern.matcher(value);
+ if (!m.matches()) {
+ return false;
+ }
+ return checker.isZipCodeValid(value);
+ }
+}
diff --git a/beanvalidationdemo/src/main/resources/META-INF/beans.xml b/beanvalidationdemo/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..8819456
--- /dev/null
+++ b/beanvalidationdemo/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/beanvalidationdemo/src/main/resources/ValidationMessages.properties b/beanvalidationdemo/src/main/resources/ValidationMessages.properties
new file mode 100644
index 0000000..627fe5e
--- /dev/null
+++ b/beanvalidationdemo/src/main/resources/ValidationMessages.properties
@@ -0,0 +1 @@
+it.plague.jeedemo.Email.message=invalid email address
\ No newline at end of file
diff --git a/beanvalidationdemo/src/test/java/it/plague/jeedemo/AddressIT.java b/beanvalidationdemo/src/test/java/it/plague/jeedemo/AddressIT.java
new file mode 100644
index 0000000..5d850e7
--- /dev/null
+++ b/beanvalidationdemo/src/test/java/it/plague/jeedemo/AddressIT.java
@@ -0,0 +1,23 @@
+package it.plague.jeedemo;
+
+import static org.junit.Assert.*;
+
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import org.junit.Test;
+
+public class AddressIT {
+
+ @Test
+ public void shouldRaiseConstraintViolationCauseInvalidZipCode() {
+ ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
+ Validator validator = vf.getValidator();
+ Address address = new Address("233 Spring Street", "New York", "NY", "DUMMY", "USA");
+ Set> violations = validator.validate(address);
+ assertEquals(1, violations.size());
+ vf.close();
+ }
+}
diff --git a/beanvalidationdemo/src/test/java/it/plague/jeedemo/CustomerIT.java b/beanvalidationdemo/src/test/java/it/plague/jeedemo/CustomerIT.java
new file mode 100644
index 0000000..e2b668c
--- /dev/null
+++ b/beanvalidationdemo/src/test/java/it/plague/jeedemo/CustomerIT.java
@@ -0,0 +1,48 @@
+package it.plague.jeedemo;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class CustomerIT {
+
+ private static ValidatorFactory vf;
+ private static Validator validator;
+
+ @BeforeClass
+ public static void init() {
+ vf = Validation.buildDefaultValidatorFactory();
+ validator = vf.getValidator();
+ }
+
+ @AfterClass
+ public static void close() {
+ vf.close();
+ }
+
+ @Test
+ public void shouldRaiseNoConstraintViolation() {
+ Customer customer = new Customer("John", "Smith", "jsmith@gmail.com");
+ Set> violations = validator.validate(customer);
+ assertEquals(0, violations.size());
+ }
+
+ @Test
+ public void shouldRaiseConstraintViolationCauseInvalidEmail() {
+ Customer customer = new Customer("John", "Smith", "DummyEmail");
+ Set> violations = validator.validate(customer);
+ assertEquals(1, violations.size());
+ assertEquals("invalid email address", violations.iterator().next().getMessage());
+ assertEquals("DummyEmail", violations.iterator().next().getInvalidValue());
+ assertEquals("{it.plague.jeedemo.Email.message}",
+ violations.iterator().next().getMessageTemplate());
+ }
+}
diff --git a/beanvalidationdemo/src/test/resources/META-INF/beans.xml b/beanvalidationdemo/src/test/resources/META-INF/beans.xml
new file mode 100644
index 0000000..8819456
--- /dev/null
+++ b/beanvalidationdemo/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 11bc87b..6a36978 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,6 +10,7 @@
cdidemo
+ beanvalidationdemo