Version 2 of JSF introduced support for Bean Validation , as described in JSF specification ( Chapter 2.5.7). To summarize: it basically states, that java bean properties , annotated with Bean Validation constraints, are going to be validated automatically by the underlying JSF implementation.
ADF as Java EE (and therefore JSF) standards based framework provides an extended functionality with a special focus on productivity and declarative development. An example of such functionality is ADF Binding Layer, which helps to access a data from user interface a unified way.
The blog post provides a sample implementation of ADF BeanValidator to close a small integration gap between a functionality specified by JSF and ADF (specifically ADF binding layer).
Note: the usage of Bean Validation might provide most benefits in case your ADF usage scenario includes an alternative to ADF Business Components, like EJBs or Webservices In case of ADF "full-stack" usage there might be no benefits in using Bean Validation comparing it to integrated validation functionality available in ADF.
Using ADF Bean Validator
The are two Projects in a Workspace: ADFBeanValidationSample and ADFBeanValidationValidator:
The first project ADFBeanValidationSample is a simple ADF Application supposed to be used in a business area "Human Resources" at some company. I will describe a structure of it and the steps used to create it very briefly.
The model consists of one java bean Employee.java with 2 properties: id and name.
The properties are annotated with JSR 303 Bean Validation constrains: @NotNull and @Size. The constrains supposed to make sure, that values for both properties are provided and size of a name fits into a boundaries defined.
There is one "service" , named HRService.java, which exposes a list of Employees as ADF Bean Data Control:
Two JSF pages (list.jsf and form.jsf) with bindings to HRService.employeeList were created in JDeveloper usual declarative way (Drag&Drop .
We start the sample -- a page list.jsf with a list of employees shows up:
It looks like we are dealing with some early-stage startup with two employees :) Lets hire a new one.
We click on a link Create - a new row gets inserted into the table. We enter a data of our new hire and click on Submit:
JSR303 Bean Validation constraint @Size(min = 3,max=20) on a property name in a bean Employee.java kicks in.
Unfortunately we can't submit the data of our new hire at a moment. We "tune" our business rules and fix our business model Employee.java this way: @Size(min = 2,max=20).
Mr. Wu is able to join our company as a result of our efforts.
Lets look at the second project ADFBeanValidationValidator for the implementation details.
ADF Bean Validator implementation details
Note: early ADF and Bean Validation integration is also described in a blog post of Romel Pino.
The second project ADFBeanValidationValidator (configured as a dependency) , provides ADFBeanValidator.java to close a gap between JSF and ADF binding layer.
ADFBeanValidator class (extends standard BeanValidator) is annotated with @FacesValidator and configured as a default:
...
@FacesValidator(value = "com.nicequestion.donatas.adf.validate.ADFBeanValidator",isDefault = true)
public class ADFBeanValidator extends BeanValidator {
...
Therefore it gets attached to every UIInput element and gets executed on a validate phase of JSF lifecycle automatically without additional configuration and development efforts.
The implementation does basically the following:
- Backups ADF bindings value expression
- Rewrites (temporary) ADF bindings value expression of UIComponent to resolve to a bean property value, e.g:
- for iterator row binding expression:
- from #{row.bindings.name.inputValue}
- to {row.bindings.name.currentRow.dataProvider.name}
- for attribute binding:
- from #{bindings.name.inputValue}
- to #{bindings.name.currentRow.dataProvider.name}
- Delegates to standard BeanValidator - validates a property.
- Restores an original ADF value expression from a backup.
ADF binding expressions don't work because they resolve to a Map interface. And a Map is not validated by a standard JSF BeanValidator.
In order to compensate that we can get a functionality of Bean Validation in ADF Project simply by including our ADFBeanValidator as a dependency.
Take a look at the source for additional implementation details - and fell free to use and adapt it for you needs in case of interest:
A complete source is also provided at Github.