Apache Onami-Validation is a Java5 compatible JSR303 (Bean Validation) integration extension for Google Guice, using http://bval.apache.org/ provider implementation.
That module has multiple purposes, such as:
Apache Onami-Validation is available on the Maven Central repo, you just need to add the dependency below in your pom.xml file:
<dependencies> ... <dependency> <groupId>org.apache.onami</groupId> <artifactId>org.apache.onami.validation</artifactId> <version>1.0.1-SNAPSHOT</version> </dependency> ... </dependencies>
Simply, the org.apache.onami.validation.ValidationModule is the Google Guice module that bootstraps Apache BVal. All users have to do is add this module when creating the Google Guice Injector:
import com.google.inject.Guice; import com.google.inject.Injector; import org.apache.onami.validation.ValidationModule; Injector injector = Guice.createInjector([...], new ValidationModule(), [...] );
Users can now implement javax.validation.ConstraintValidator classes that require Dependency Injection by Google Guice:
import javax.validation.ConstraintValidator; public class MyCustomValidator implements ConstraintValidator<MyAssert, MyType> { private final MyExternalService service; @javax.inject.Inject public MyCustomValidator( MyExternalService service ) { this.service = service; } public void initialize( MyAssert annotation ) { // do something } public boolean isValid( MyType value, ConstraintValidatorContext context ) { return value == null || service.doSomething( value ); } }
Don't forget to bind the MyExternalService class in the Google Guice Binder!!!
Clients can easily inject javax.validation.Validator instances into their custom components just marking it using @Inject annotation:
import javax.validation.Validator; public class MyValidatorClient { @Inject private Validator validator; public void setValidator( Validator validator ) { this.validator = validator; } // ... }
When obtaining MyValidatorClient instances from the Injector, the javax.validation.Validator will be automagically bound.
Taking advantage of the Apache BVal extension to validate method arguments, the ValidationModule comes with an AOP interceptor, automatically initialized in the org.apache.onami.validation.ValidationModule, that makes easy method arguments validation.
All users have to do is annotate interested methods with org.apache.onami.validation.Validate annotation, then annotate arguments with constraints, as follows below:
import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.apache.onami.validation.Validate; public class MyService { @Validate( groups = { MyGroup.class }, validateReturnedValue = true ) public Country insertCountry( @NotNull(groups = { MyGroup.class }) String name, @NotNull(groups = { MyGroup.class }) @Size(max = 2, groups = { MyGroup.class, MyOtherGroup.class }) String iso2Code, @NotNull(groups = { MyGroup.class }) @Size(max = 3, groups = { MyGroup.class, MyOtherGroup.class }) String iso3Code ) { return ...; } }
The @Validate annotation supports following arguments:
@Validate annotations supports special configuration settings to re-throw validations error in a custom exception.
When specifying rethrowExceptionsAs parameter, it is required that the target exception type has the constructor with Throwable single argument; when specifying both rethrowExceptionsAs and exceptionMessage parameters, it is required that the target exception type has the constructor with String, Throwable arguments; specifying the exceptionMessage parameter only, doesn't have any effect.
exceptionMessage supports java.util.Formatter place holders, intercepted method arguments will be used as message format arguments.
For example, given a generic exception:
class DummyException extends Exception { public DummyException( Throwable cause ) { super( cause ); } public DummyException( String message, Throwable cause ) { super( message, cause ); } }
Users can annotate service methods as below:
import javax.validation.constraints.NotNull; import org.apache.onami.validation.Validate; public class MyService { @Validate( rethrowExceptionsAs = DummyException.class ) public Country retrieve( @NotNull String name ) { return ...; } }
adopting that approach, the DummyException( Throwable ) constructor will be used; otherwise:
import javax.validation.constraints.NotNull; import org.apache.onami.validation.Validate; public class MyService { @Validate( exceptionMessage = "This is just a dummy message %s", rethrowExceptionsAs = DummyException.class ) public Country retrieve( @NotNull String name ) { return ...; } }
the DummyException will be thrown using the DummyException( String, Throwable ) constructor.