Bug 279166 - [DataBinding] JSR 303: Bean Validation
Summary: [DataBinding] JSR 303: Bean Validation
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.5   Edit
Hardware: All All
: P3 enhancement with 3 votes (vote)
Target Milestone: ---   Edit
Assignee: Platform UI Triaged CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2009-06-04 17:09 EDT by Christian Flandorfer CLA
Modified: 2015-05-06 14:04 EDT (History)
15 users (show)

See Also:


Attachments
A JFace validator using JSR-303 to validate a single property (5.48 KB, text/plain)
2010-01-15 03:59 EST, Marcus Ilgner CLA
no flags Details
JSR303 single property validator decoupled from ControlDecoration (3.91 KB, application/octet-stream)
2010-03-02 11:48 EST, Henno Vermeulen CLA
no flags Details
New JSR-303 JFace Databinding Validator with sample (simple main + RCP) (4.15 MB, application/zip)
2011-11-09 03:16 EST, Angelo ZERR CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Flandorfer CLA 2009-06-04 17:09:34 EDT
At Java One 2009 the Project Bean Validation (JSR 303) was introduced. It would be nice if this kind of validation can be used with JFace DataBinding out of the box. I think the main advantage that the validation is only defined at one point would allow to imlement RCP applications that are easier to maintain.
Comment 1 Matthew Hall CLA 2009-06-09 15:25:39 EDT
For reference the specification can be downloaded here:

http://jcp.org/aboutJava/communityprocess/pfd/jsr303/index.html

This actually looks pretty slick.  It would be interesting to compare and contrast this with EMF validation.
Comment 2 Matthew Hall CLA 2009-06-16 16:23:18 EDT
One weakness I've noticed in the JSR is that it is based around validation errors, not lesser statuses like warning or info.  Sometimes you want to display a hint for something that could _possibly_ be an error, or when some data deviates from a typical pattern.  Validation statuses of this variety should not alert the user to a potential problem, but not block them from proceeding.  Example: the New Class wizard complains if the class name begins with a lowercase letter--however the user is not prevented from creating it.
Comment 3 Matthew Hall CLA 2010-01-15 02:00:29 EST
Now that JSR303 has been voted on and approved by the JCP we can move forward with this.

I have a full plate and am unlikely to get around to this one myself.  Unassigning the bug and adding helpwanted tag.

If anyone wants to step up and tackle this bug I will gladly provide guidance / assistance.
Comment 4 Marcus Ilgner CLA 2010-01-15 03:58:53 EST
Some time ago, I wrote a validator for JFace databinding which uses JSR-303 facilities to validate a single property.
However I'm still unsure on how to implement a validator based on the whole bean or multiple properties. The JSR-303 API can only validate single properties or whole beans and I'm still unsure on how to observe the whole bean or multiple properties on the JFace side.
Attached you'll find my validator, maybe it helps.
Comment 5 Marcus Ilgner CLA 2010-01-15 03:59:52 EST
Created attachment 156209 [details]
A JFace validator using JSR-303 to validate a single property
Comment 6 Matthew Hall CLA 2010-01-27 02:29:09 EST
Thanks Marcus!  I finally found some time to review this tonight.  A few comments:
* There are too many concerns wrapped into one class (bean property validation + control decoration), and due to the way databinding is modularized into separate bundles for bean support vs SWT+JFace support, I cannot put this class into one or the other without introducing an arbitrary dependency.
* Since you want to display a validation status that is not necessarily tied to a Binding per se, I think that implementing this as a ValidationStatusProvider instead of IValidator will be more generally useful.
* We already have support in place via ControlDecorationSupport for wiring up a ValidationStatusProvider to ControlDecorations
* You may want to explicitly observe the bean property in an IObservableValue and monitor it for changes, so that validation status can be refreshed automatically instead of on demand.
Comment 7 Henno Vermeulen CLA 2010-03-02 11:48:05 EST
Created attachment 160643 [details]
JSR303 single property validator decoupled from ControlDecoration

I am a new Eclipse RCP programmer and was looking how to use JSR 303 bean validation inside Eclipse. Using the code provided by Marcus and the comments from Matthew I created a slimmed down validator class (see attachment) for single properties.

To get the control decorations next to a bound UI element I simply use a one liner:

ControlDecorationSupport.create(binding, SWT.TOP | SWT.LEFT);

where binding is the Binding returned by DataBindingContext.bindValue(..). (Unfortunately use of org.eclipse.jface.internal.databinding.provisional.fieldassist.ControlDecorationSupport is discouraged)

The coming time I will look into cross-property validation. I will first focus on getting the message displayed above a form, maybe by using a MultiValidator (which extends ValidationStatusProvider as suggested by Matthew).
Comment 8 Henno Vermeulen CLA 2010-03-05 11:10:51 EST
Well, I couldn't really find out how to use a MultiValidator or a ValidationStatusProvider directly to do cross-field validation because its validate() method is never called by binding context when a field changes.

What follows only applies when you are willing to use the IMessageManager of UI forms.

Showing cross-field validation errors using the IMessageManager was very simple to make. I register one IValueChangeListener for each of the IObservableValues in my data binding context. This listener simply uses JSR 303 to validate the entire entity from my model and directly clears or adds error messages to the IMessageManager which I get from my ManagedForm. This way I don't even need a MultiValidator and I bypass Eclipse's validation system completely.

This is probably not the cleanest way to do it; the model still gets invalid values, but I will simply disable save when this is the case.

As a side-effect of still using the SinglePropertyValidator which prevents the model from getting invalid single properties, my form header only shows cross-field validation error messages. When I do not use the SinglePropertyValidator it also works and the header now also shows validation errors on single properties. The big difference is that these invalid properties already entered the model.

When looking at the IMessageManager source it even seems that it also has support for automatically creating ControlDecorations. If this works, another approach would be to throw away the SinglePropertyValidator and let the IMessageManager know which Control violates single property constraints but use a Control value of null (like I already do now) when it is a cross property constraint.
Comment 9 Matthew Hall CLA 2010-03-09 04:08:04 EST
At a fundamental level I don't think it will be possible to prevent invalid values from getting back to the model with JSR303 validators, since the model is where JSR303 wants to do its validation.  Hence you have to push potentially invalid data to the model before you can even kick off the validator.

Although it might be possible to clone beans and use some clever combination of MultiValidator  and it's validated observables (e.g. MultiValidator.observeValidatedValue) and use one bean as a staging area for validation testing, so that the "true" bean will only get updates when all the validators pass.

The critical missing piece here is to identify at runtime the properties that the validators depend on, to register change listeners on those properties, and to automatically revalidate as those properties change.
Comment 10 Angelo ZERR CLA 2011-11-09 03:16:20 EST
Created attachment 206651 [details]
New JSR-303 JFace Databinding Validator with sample (simple main + RCP)

Here a patch which contains projects explained at http://wiki.eclipse.org/JFace_Data_Binding/JSR303BeanJFaceDatabindingValidation

This patch contains several projects :

    * org.eclipse.core.databinding.validation.jsr303 : JSR-303 support for JFace Databinding Validators source.
    * org.eclipse.core.databinding.validation.jsr303.samples : JSR-303 support for JFace Databinding Validators sample with Java main.
    * org.eclipse.core.databinding.validation.jsr303.samples.rcp : JSR-303 support for JFace Databinding Validators with Eclipse RCP (in an OSGi context).

External budnles :

    * com.springsource.javax.validation : JSR-303 API.
    * org.apache.bval.org.apache.bval.bundle : JSR-303 implementation with Apache Bean Validation.
    * org.hibernate.validator, slf4j.api, slf4j.simple : JSR-303 implementation with Hibernate Validation.

In OSGi context to register JSR-303 implementation (to launch RCP sample application), there are OSGi fragments :

    * javax.validation.osgi.config.fragment.hibernatevalidator: OSGi fragment which configures with SPI provider the Hibernate Validator with the file META-INF/services/javax.validation.spi.ValidationProvider which contains org.hibernate.validator.HibernateValidator.
    * javax.validation.osgi.config.fragment.apachebval: OSGi fragment which configures with SPI provider the Apache Bean Validator with the file META-INF/services/javax.validation.spi.ValidationProvider which contains org.apache.bval.jsr303.ApacheValidationProvider.

and OSGi bundles

    * javax.validation.osgi.config.bundle.hibernatevalidator: OSGi bundle which registers in the registry services the Hibernate Validator instance of javax.validation.ValidatorFactory
    * javax.validation.osgi.config.bundle.apachebval: OSGi bundle which registers in the registry services the Apache Bean Validator instance of javax.validation.ValidatorFactory

This support looks like than "attached 156209" but it provides some factory to create JSR-303 JFace Validator, provides the capability to retrieve the JSR-303 ValidatorFactory from the OSGi registry or fragment.

We are using this support in our RCP/RAP application.See RAP demo here  http://xdocreport-rap.opensagres.cloudbees.net/xdocreport?startup=fr.opensagres.xdocreport.eclipse.application

Hope you will like it.

Regards Angelo