diff --git a/README.md b/README.md
index 2cd837683..f2682079e 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ Here is a brief summary of each module:
- `restx-factory`: RESTX Dependency Injection (DI) container. Brought as transitive dependency from restx-core.
- `restx-classloader`: Hot reload / hot compile support
- `restx-apidocs-doclet`: Some javadoc doclets used when generating apidocs
-- `restx-core`: Core module, includes the REST framework, base security, JSON support, Validation, ...
+- `restx-core`: Core module, includes the REST framework, base security, JSON support, ...
*By relying on `restx-core` module, every modules described above will be retrieved as transitive dependencies*
@@ -63,6 +63,7 @@ Here is a brief summary of each module:
- `restx-specs-tests-java8`: Support for java 8 time API during specs tests
- `restx-specs-server`: Enables using RESTX specs as HTTP mocks (running a server serving spec files responses given spec files requests).
- `restx-factory-testing`: A module dedicated to test `restx-factory` features involving annotation processing.
+- `restx-validation`: Bean validation support (based on `hibernate-validator` implementation) for POJOs BODY parameters
#### MongoDB support through Jongo API:
diff --git a/pom.xml b/pom.xml
index 43d9267bc..e0389f76f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -158,6 +158,7 @@
restx-shell-manager
restx-build-shell
restx-specs-shell
+ restx-validation
diff --git a/restx-core-annotation-processor/src/main/java/restx/annotations/Annotations.java b/restx-core-annotation-processor/src/main/java/restx/annotations/Annotations.java
new file mode 100644
index 000000000..eae7b200e
--- /dev/null
+++ b/restx-core-annotation-processor/src/main/java/restx/annotations/Annotations.java
@@ -0,0 +1,38 @@
+package restx.annotations;
+
+import com.sun.tools.javac.code.Attribute;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author fcamblor
+ */
+public class Annotations {
+ public static String[] getAnnotationClassValuesAsFQCN(VariableElement p, Class annotationClazz, String methodName) {
+ List extends AnnotationMirror> annotationMirrors = p.getAnnotationMirrors();
+ for(AnnotationMirror annotationMirror : annotationMirrors){
+ if(annotationMirror.getAnnotationType().toString().equals(annotationClazz.getCanonicalName())){
+ for(Map.Entry extends ExecutableElement,? extends AnnotationValue> entry : annotationMirror.getElementValues().entrySet()){
+ if(entry.getKey().getSimpleName().contentEquals(methodName)){
+ Attribute.Array array = (Attribute.Array) entry.getValue();
+
+ List fqcns = new ArrayList<>();
+ for(Attribute attribute : array.getValue()) {
+ DeclaredType type = (DeclaredType) attribute.getValue();
+ fqcns.add(type.toString());
+ }
+ return fqcns.toArray(new String[fqcns.size()]);
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/restx-core-annotation-processor/src/main/java/restx/annotations/processor/RestxAnnotationProcessor.java b/restx-core-annotation-processor/src/main/java/restx/annotations/processor/RestxAnnotationProcessor.java
index 5c2aa30ae..af8859f2b 100644
--- a/restx-core-annotation-processor/src/main/java/restx/annotations/processor/RestxAnnotationProcessor.java
+++ b/restx-core-annotation-processor/src/main/java/restx/annotations/processor/RestxAnnotationProcessor.java
@@ -1,6 +1,7 @@
package restx.annotations.processor;
import com.google.common.base.CaseFormat;
+import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.*;
@@ -14,6 +15,7 @@
import restx.http.HttpStatus;
import restx.security.PermitAll;
import restx.security.RolesAllowed;
+import restx.validation.ValidatedFor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
@@ -38,6 +40,13 @@
public class RestxAnnotationProcessor extends RestxAbstractProcessor {
final Template routerTpl;
+ private static final Function FQN_EXTRACTOR = new Function(){
+ @Override
+ public String apply(Class clazz) {
+ return clazz.getCanonicalName();
+ }
+ };
+
public RestxAnnotationProcessor() {
routerTpl = Mustaches.compile(RestxAnnotationProcessor.class, "RestxRouter.mustache");
}
@@ -163,11 +172,19 @@ private void buildResourceMethodParams(ResourceMethodAnnotation annotation, Reso
}
}
+ ValidatedFor validatedFor = p.getAnnotation(ValidatedFor.class);
+
+ String[] validationGroups = new String[0];
+ if(validatedFor != null) {
+ validationGroups = Annotations.getAnnotationClassValuesAsFQCN(p, ValidatedFor.class, "value");
+ }
+
resourceMethod.parameters.add(new ResourceMethodParameter(
p.asType().toString(),
paramName,
reqParamName,
- parameterKind));
+ parameterKind,
+ validationGroups));
}
if (!pathParamNamesToMatch.isEmpty()) {
error(
@@ -492,8 +509,16 @@ private static class ResourceMethodParameter {
final String name;
final String reqParamName;
final ResourceMethodParameterKind kind;
+ final List validationGroupsFQNs;
+
+ private static final Function CLASS_APPENDER_FCT = new Function() {
+ @Override
+ public String apply(String fqn) {
+ return fqn+".class";
+ }
+ };
- private ResourceMethodParameter(String type, String name, String reqParamName, ResourceMethodParameterKind kind) {
+ private ResourceMethodParameter(String type, String name, String reqParamName, ResourceMethodParameterKind kind, String[] validationGroupsFQNs) {
Matcher guavaOptionalMatcher = guavaOptionalPattern.matcher(type);
Matcher java8OptionalMatcher = java8OptionalPattern.matcher(type);
this.realType = type;
@@ -513,6 +538,15 @@ private ResourceMethodParameter(String type, String name, String reqParamName, R
this.name = name;
this.reqParamName = reqParamName;
this.kind = kind;
+ this.validationGroupsFQNs = Arrays.asList(validationGroupsFQNs);
+ }
+
+ public Optional joinedValidationGroupFQNExpression(){
+ if(this.validationGroupsFQNs == null || this.validationGroupsFQNs.isEmpty()) {
+ return Optional.absent();
+ } else {
+ return Optional.of(Joiner.on(", ").join(Iterables.transform(this.validationGroupsFQNs, CLASS_APPENDER_FCT)));
+ }
}
}
@@ -539,7 +573,8 @@ public String fetchFromReqCode(ResourceMethodParameter parameter) {
},
BODY {
public String fetchFromReqCode(ResourceMethodParameter parameter) {
- return String.format("checkValid(validator, body)", parameter.type);
+ Optional validationGroupsExpr = parameter.joinedValidationGroupFQNExpression();
+ return String.format("checkValid(validator, body%s)", validationGroupsExpr.isPresent()?","+validationGroupsExpr.get():"");
}
},
CONTEXT {
diff --git a/restx-core-annotation-processor/src/main/resources/restx/annotations/processor/RestxRouter.mustache b/restx-core-annotation-processor/src/main/resources/restx/annotations/processor/RestxRouter.mustache
index b07e7c539..4b2ea2183 100644
--- a/restx-core-annotation-processor/src/main/resources/restx/annotations/processor/RestxRouter.mustache
+++ b/restx-core-annotation-processor/src/main/resources/restx/annotations/processor/RestxRouter.mustache
@@ -32,7 +32,7 @@ public class {{router}} extends RestxRouter {
final EntityRequestBodyReaderRegistry readerRegistry,
final EntityResponseWriterRegistry writerRegistry,
final MainStringConverter converter,
- final Validator validator,
+ final Optional validator,
final RestxSecurityManager securityManager) {
super(
"{{routerGroup}}", "{{router}}", new RestxRoute[] {
diff --git a/restx-core/pom.xml b/restx-core/pom.xml
index 9e497b88b..83cb31b4e 100644
--- a/restx-core/pom.xml
+++ b/restx-core/pom.xml
@@ -25,7 +25,7 @@
2.3
2.3.3
1.13
- 5.0.1.Final
+ 1.1.0.Final
0.9.9-RC1
1
4.11
@@ -94,9 +94,9 @@
${slf4j-api.version}
- org.hibernate
- hibernate-validator
- ${hibernate-validator.version}
+ javax.validation
+ validation-api
+ ${validation-api.version}
org.reflections
diff --git a/restx-core/src/main/java/restx/validation/ValidatedFor.java b/restx-core/src/main/java/restx/validation/ValidatedFor.java
new file mode 100644
index 000000000..d38952583
--- /dev/null
+++ b/restx-core/src/main/java/restx/validation/ValidatedFor.java
@@ -0,0 +1,13 @@
+package restx.validation;
+
+import java.lang.annotation.*;
+
+/**
+ * @author fcamblor
+ */
+@Target(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface ValidatedFor {
+ Class[] value();
+}
diff --git a/restx-core/src/main/java/restx/validation/Validations.java b/restx-core/src/main/java/restx/validation/Validations.java
index 65f4f74ab..bef2dcb4f 100644
--- a/restx-core/src/main/java/restx/validation/Validations.java
+++ b/restx-core/src/main/java/restx/validation/Validations.java
@@ -1,9 +1,11 @@
package restx.validation;
import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
+import javax.validation.groups.Default;
import java.util.Set;
/**
@@ -12,11 +14,27 @@
* Time: 9:57 PM
*/
public class Validations {
+
+ /**
+ * @deprecated Kept for backward compat. Use checkValid(Optional<Validator>, T, Class...) instead
+ */
+ @Deprecated
public static T checkValid(Validator validator, T o) {
- Set> violations = validator.validate(o);
- if (!violations.isEmpty()) {
- throw new IllegalArgumentException(Joiner.on(", ").join(violations));
+ return checkValid(Optional.of(validator), o);
+ }
+
+ public static T checkValid(Optional validator, T o, Class... groups) {
+ if(validator.isPresent()) {
+ if(groups == null || groups.length==0) {
+ groups = new Class[]{ Default.class };
+ }
+
+ Set> violations = validator.get().validate(o, groups);
+ if (!violations.isEmpty()) {
+ throw new IllegalArgumentException(Joiner.on(", ").join(violations));
+ }
}
+
return o;
}
}
diff --git a/restx-core/src/main/java/restx/validation/ValidatorFactory.java b/restx-core/src/main/java/restx/validation/ValidatorFactory.java
deleted file mode 100644
index 1ff510ff8..000000000
--- a/restx-core/src/main/java/restx/validation/ValidatorFactory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package restx.validation;
-
-import org.hibernate.validator.HibernateValidator;
-import restx.factory.*;
-
-import javax.inject.Named;
-import javax.validation.Validation;
-import javax.validation.Validator;
-
-/**
- * User: xavierhanin
- * Date: 2/3/13
- * Time: 9:48 PM
- */
-@Module
-public class ValidatorFactory {
- public static final String VALIDATOR_NAME = "validator";
- public static final Name VALIDATOR = Name.of(Validator.class, VALIDATOR_NAME);
-
- @Provides @Named(VALIDATOR_NAME)
- public Validator validator() {
- return Validation.byProvider(HibernateValidator.class).configure()
- .ignoreXmlConfiguration().buildValidatorFactory().getValidator();
- }
-}
diff --git a/restx-core/src/main/java/restx/validation/stereotypes/FormValidations.java b/restx-core/src/main/java/restx/validation/stereotypes/FormValidations.java
new file mode 100644
index 000000000..4aaec3864
--- /dev/null
+++ b/restx-core/src/main/java/restx/validation/stereotypes/FormValidations.java
@@ -0,0 +1,14 @@
+package restx.validation.stereotypes;
+
+import javax.validation.groups.Default;
+
+/**
+ * @author fcamblor
+ */
+public interface FormValidations {
+ public static final String DefaultFQN = "javax.validation.groups.Default";
+ public static final String CreateFQN = "restx.validation.stereotypes.FormValidations.Create";
+ public static interface Create extends Default{}
+ public static final String UpdateFQN = "restx.validation.stereotypes.FormValidations.Update";
+ public static interface Update extends Default{}
+}
diff --git a/restx-samplest/pom.xml b/restx-samplest/pom.xml
index 09c60036b..42c570397 100644
--- a/restx-samplest/pom.xml
+++ b/restx-samplest/pom.xml
@@ -30,6 +30,11 @@
restx-core
${restx.version}
+
+ io.restx
+ restx-validation
+ ${restx.version}
+
io.restx
restx-core-annotation-processor
@@ -123,6 +128,20 @@
-restx-target-dir ${project.basedir}/target/classes
+
diff --git a/restx-samplest/src/main/java/samplest/validation/POJO.java b/restx-samplest/src/main/java/samplest/validation/POJO.java
new file mode 100644
index 000000000..f9b567670
--- /dev/null
+++ b/restx-samplest/src/main/java/samplest/validation/POJO.java
@@ -0,0 +1,52 @@
+package samplest.validation;
+
+import org.hibernate.validator.constraints.Email;
+import restx.validation.stereotypes.FormValidations;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+public class POJO {
+ @NotNull(groups={FormValidations.Update.class})
+ Long id;
+ @NotNull
+ @Size(min=10, groups={ValidationResource.MyCustomValidationGroup.class})
+ String name;
+ @Valid
+ SubPOJO subPOJO;
+ @Email
+ String email;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public SubPOJO getSubPOJO() {
+ return subPOJO;
+ }
+
+ public void setSubPOJO(SubPOJO subPOJO) {
+ this.subPOJO = subPOJO;
+ }
+}
diff --git a/restx-samplest/src/main/java/samplest/validation/SubPOJO.java b/restx-samplest/src/main/java/samplest/validation/SubPOJO.java
new file mode 100644
index 000000000..dd72ac8fa
--- /dev/null
+++ b/restx-samplest/src/main/java/samplest/validation/SubPOJO.java
@@ -0,0 +1,16 @@
+package samplest.validation;
+
+import javax.validation.constraints.Size;
+
+public class SubPOJO {
+ @Size(min=10)
+ String label;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+}
diff --git a/restx-samplest/src/main/java/samplest/validation/ValidationResource.java b/restx-samplest/src/main/java/samplest/validation/ValidationResource.java
new file mode 100644
index 000000000..c702f2695
--- /dev/null
+++ b/restx-samplest/src/main/java/samplest/validation/ValidationResource.java
@@ -0,0 +1,41 @@
+package samplest.validation;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import restx.annotations.POST;
+import restx.annotations.PUT;
+import restx.annotations.Param;
+import restx.annotations.RestxResource;
+import restx.factory.Component;
+import restx.security.PermitAll;
+import restx.validation.ValidatedFor;
+import restx.validation.stereotypes.FormValidations;
+
+/**
+ * @author fcamblor
+ */
+@RestxResource @Component
+public class ValidationResource {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ValidationResource.class);
+
+ public static interface MyCustomValidationGroup{}
+
+ @PermitAll
+ @POST("/valid/pojos")
+ public void createPOJOWithoutAnnotation(POJO myPojo) {
+ LOG.info("Pojo {} {} created !", myPojo.getName(), myPojo.getSubPOJO().getLabel());
+ }
+
+ @PermitAll
+ @POST("/valid/pojos2")
+ public void createPOJOWithAnnotation(@ValidatedFor(FormValidations.Create.class) POJO myPojo) {
+ LOG.info("Pojo {} {} created !", myPojo.getName(), myPojo.getSubPOJO().getLabel());
+ }
+
+ @PermitAll
+ @PUT("/valid/pojos/{id}")
+ public void createPOJOWithoutAnnotation(Long id, @ValidatedFor({MyCustomValidationGroup.class, FormValidations.Update.class}) POJO myPojo) {
+ LOG.info("Pojo {} {} updated !", myPojo.getName(), myPojo.getSubPOJO().getLabel());
+ }
+}
diff --git a/restx-samplest/src/main/resources/specs/core/Hello_msg_20140427_170121.spec.yaml b/restx-samplest/src/main/resources/specs/core/Hello_msg_20140427_170121.spec.yaml
new file mode 100644
index 000000000..595683e91
--- /dev/null
+++ b/restx-samplest/src/main/resources/specs/core/Hello_msg_20140427_170121.spec.yaml
@@ -0,0 +1,11 @@
+title: Hello msg 20140427 170121
+given:
+ - time: 2014-04-27T17:01:21.795+02:00
+wts:
+ - when: |
+ GET core/hellomsg?who=xavier
+ Cookie: RestxSession={"_expires":"2014-05-27T17:01:21.795+02:00","principal":"admin","sessionKey":"81b92e9b-49eb-4c54-9c78-79a4a79feae5"}; RestxSessionSignature=g3KnRfPE2SAaoXbR3Iq7XHv5L3M=
+ then: |
+ {
+ "msg" : "hello xavier"
+ }
diff --git a/restx-samplest/src/main/resources/specs/validation/createPOJO_ko.spec.yaml b/restx-samplest/src/main/resources/specs/validation/createPOJO_ko.spec.yaml
new file mode 100644
index 000000000..13fa51d4b
--- /dev/null
+++ b/restx-samplest/src/main/resources/specs/validation/createPOJO_ko.spec.yaml
@@ -0,0 +1,34 @@
+title: Create Validation POJO - KO
+given:
+ - time: 2014-12-24T17:01:21.795+02:00
+wts:
+ - when: |
+ POST valid/pojos
+ {"email": "toto@acme.com", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 400
+ - when: |
+ POST valid/pojos
+ {"name": "blah", "email": "toto", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 400
+ - when: |
+ POST valid/pojos
+ {"name": "blah", "email": "toto@acme.com", "subPOJO": { "label": "a label" }}
+ then: |
+ 400
+ - when: |
+ POST valid/pojos2
+ {"email": "toto@acme.com", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 400
+ - when: |
+ POST valid/pojos2
+ {"name": "blah", "email": "toto", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 400
+ - when: |
+ POST valid/pojos2
+ {"name": "blah", "email": "toto@acme.com", "subPOJO": { "label": "a label" }}
+ then: |
+ 400
diff --git a/restx-samplest/src/main/resources/specs/validation/createPOJO_ok.spec.yaml b/restx-samplest/src/main/resources/specs/validation/createPOJO_ok.spec.yaml
new file mode 100644
index 000000000..82ecd04f9
--- /dev/null
+++ b/restx-samplest/src/main/resources/specs/validation/createPOJO_ok.spec.yaml
@@ -0,0 +1,14 @@
+title: Create Validation POJO - OK
+given:
+ - time: 2014-12-24T17:01:21.795+02:00
+wts:
+ - when: |
+ POST valid/pojos
+ {"name": "blah", "email": "toto@acme.com", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 204
+ - when: |
+ POST valid/pojos2
+ {"name": "blah", "email": "toto@acme.com", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 204
diff --git a/restx-samplest/src/main/resources/specs/validation/updatePOJO_ko.spec.yaml b/restx-samplest/src/main/resources/specs/validation/updatePOJO_ko.spec.yaml
new file mode 100644
index 000000000..8cde5c8e4
--- /dev/null
+++ b/restx-samplest/src/main/resources/specs/validation/updatePOJO_ko.spec.yaml
@@ -0,0 +1,24 @@
+title: Update Validation POJO - KO
+given:
+ - time: 2014-12-24T17:01:21.795+02:00
+wts:
+ - when: |
+ PUT valid/pojos/123
+ {"name": "a very long name", "email": "toto@acme.com", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 400
+ - when: |
+ PUT valid/pojos/123
+ {"id": 123, "name": "a name", "email": "toto@acme.com", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 400
+ - when: |
+ PUT valid/pojos/123
+ {"id": 123, "name": "a very long name", "email": "toto", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 400
+ - when: |
+ PUT valid/pojos/123
+ {"id": 123, "name": "a very long name", "email": "toto@acme.com", "subPOJO": { "label": "a label" }}
+ then: |
+ 400
diff --git a/restx-samplest/src/main/resources/specs/validation/updatePOJO_ok.spec.yaml b/restx-samplest/src/main/resources/specs/validation/updatePOJO_ok.spec.yaml
new file mode 100644
index 000000000..286f73326
--- /dev/null
+++ b/restx-samplest/src/main/resources/specs/validation/updatePOJO_ok.spec.yaml
@@ -0,0 +1,9 @@
+title: Create Validation POJO - OK
+given:
+ - time: 2014-12-24T17:01:21.795+02:00
+wts:
+ - when: |
+ PUT valid/pojos/123
+ {"id": 123, "name": "a very long name", "email": "toto@acme.com", "subPOJO": { "label": "a very long label" }}
+ then: |
+ 204
diff --git a/restx-samplest/src/test/java/samplest/validation/ValidationResourceTest.java b/restx-samplest/src/test/java/samplest/validation/ValidationResourceTest.java
new file mode 100644
index 000000000..e1d6d7c6e
--- /dev/null
+++ b/restx-samplest/src/test/java/samplest/validation/ValidationResourceTest.java
@@ -0,0 +1,13 @@
+package samplest.validation;
+
+import org.junit.runner.RunWith;
+import restx.tests.FindSpecsIn;
+import restx.tests.RestxSpecTestsRunner;
+
+/**
+ * @author fcamblor
+ */
+@RunWith(RestxSpecTestsRunner.class)
+@FindSpecsIn("specs/validation")
+public class ValidationResourceTest {
+}
diff --git a/restx-validation/md.restx.json b/restx-validation/md.restx.json
new file mode 100644
index 000000000..1489f5671
--- /dev/null
+++ b/restx-validation/md.restx.json
@@ -0,0 +1,19 @@
+{
+ "parent": "io.restx:restx-parent:${restx.version}",
+ "module": "io.restx:restx-validation:${restx.version}",
+
+ "properties": {
+ "@files": ["../restx.build.properties.json"]
+ },
+
+ "dependencies": {
+ "compile": [
+ "io.restx:restx-factory:${restx.version}",
+ "org.hibernate:hibernate-validator:${hibernate-validator.version}",
+ "javax.el:el-api:${el.api.version}"
+ ],
+ "runtime": [
+ "org.glassfish.web:el-impl:${el.api.version}"
+ ]
+ }
+}
diff --git a/restx-validation/module.ivy b/restx-validation/module.ivy
new file mode 100644
index 000000000..d04220028
--- /dev/null
+++ b/restx-validation/module.ivy
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/restx-validation/pom.xml b/restx-validation/pom.xml
new file mode 100644
index 000000000..fba93c314
--- /dev/null
+++ b/restx-validation/pom.xml
@@ -0,0 +1,55 @@
+
+
+
+ io.restx
+ restx-parent
+ 0.34-SNAPSHOT
+
+ 4.0.0
+
+ io.restx
+ restx-validation
+ 0.34-SNAPSHOT
+ jar
+ restx-validation
+
+
+ 0.34-SNAPSHOT
+ 1.7
+ 1.7
+ 5.0.1.Final
+ 2.2
+
+
+
+
+ io.restx
+ restx-factory
+ ${restx.version}
+
+
+ org.hibernate
+ hibernate-validator
+ ${hibernate-validator.version}
+
+ compile
+
+
+ javax.el
+ el-api
+ ${el.api.version}
+
+
+ org.glassfish.web
+ el-impl
+ ${el.api.version}
+ runtime
+
+
+
+
\ No newline at end of file
diff --git a/restx-validation/src/main/java/restx/validation/ValidatorFactory.java b/restx-validation/src/main/java/restx/validation/ValidatorFactory.java
new file mode 100644
index 000000000..b8cd83b0a
--- /dev/null
+++ b/restx-validation/src/main/java/restx/validation/ValidatorFactory.java
@@ -0,0 +1,38 @@
+package restx.validation;
+
+import org.hibernate.validator.HibernateValidator;
+import org.hibernate.validator.HibernateValidatorConfiguration;
+import restx.factory.Module;
+import restx.factory.Name;
+import restx.factory.Provides;
+
+import javax.inject.Named;
+import javax.validation.Validation;
+import javax.validation.Validator;
+
+/**
+ * User: xavierhanin
+ * Date: 2/3/13
+ * Time: 9:48 PM
+ */
+@Module
+public class ValidatorFactory {
+ public static final String VALIDATOR_NAME = "hibernate.validator";
+ public static final String IGNORE_XML_CONFIGURATION_NAME = "hibernate.validator.ignore.xml.configuration";
+ public static final Name VALIDATOR = Name.of(Validator.class, VALIDATOR_NAME);
+
+ @Provides @Named(VALIDATOR_NAME)
+ public Validator validator(@Named(IGNORE_XML_CONFIGURATION_NAME) Boolean ignoreXmlConfiguration) {
+ HibernateValidatorConfiguration config = Validation.byProvider(HibernateValidator.class).configure();
+ if(ignoreXmlConfiguration) {
+ config.ignoreXmlConfiguration();
+ }
+ return config.buildValidatorFactory().getValidator();
+ }
+
+ // Perf improvement to greatly fasten startup time
+ @Provides @Named(IGNORE_XML_CONFIGURATION_NAME)
+ public Boolean ignoreXmlConfigurationFlag(){
+ return Boolean.TRUE;
+ }
+}
diff --git a/restx.build.properties.json b/restx.build.properties.json
index 375fc7662..ceb755e65 100644
--- a/restx.build.properties.json
+++ b/restx.build.properties.json
@@ -16,6 +16,7 @@
"snakeyaml.version": "1.13",
"hibernate-validator.version": "5.0.1.Final",
+ "el.api.version": "2.2",
"reflections.version": "0.9.9-RC1",
"janino.version": "2.6.1",