Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "JFace Data Binding/JSR303BeanJFaceDatabindingValidation"

(= Create Jsr303BeanValidator)
(Use Jsr303BeanValidator)
Line 150: Line 150:
 
==== Use Jsr303BeanValidator ====
 
==== Use Jsr303BeanValidator ====
  
At this step you can use the validator in your DatabindingContext :  
+
At this step you can use the validator in your DatabindingContext by creating an instanceof of UpdateValueStrategy  :  
  
 
<source lang="java" >
 
<source lang="java" >
 
IValidator validator = new Jsr303BeanValidator(Person.class, "email");
 
IValidator validator = new Jsr303BeanValidator(Person.class, "email");
 
UpdateValueStrategy updateValueStrategy = new UpdateValueStrategy().setAfterConvertValidator(validator);
 
UpdateValueStrategy updateValueStrategy = new UpdateValueStrategy().setAfterConvertValidator(validator);
 +
</source>
 +
 +
Here the full code to bind SWT Text with the "email" property of Person instance :
 +
 +
<source lang="java" >
 +
Text emailText = ....
 +
Person model = ...
 +
IObservableValue swtEmailTextObservableValue = SWTObservables.observeText(emailText, SWT.Modify);
 +
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
 +
dataBindingContext.bindValue(
 +
swtEmailTextObservableValue,
 +
modelEmailObserveValue,
 +
new UpdateValueStrategy()
 +
.setAfterConvertValidator(new Jsr303BeanValidator(
 +
Person.class, "email")), null);
 +
</source>
 +
 +
==== Use Jsr303UpdateValueStrategyFactory ====
 +
 +
You can simplify the creation of the JSR-303 UpdateValueStrategy. Instead of doing that:
 +
 +
<source lang="java" >
 +
UpdateValueStrategy updateValueStrategy = new UpdateValueStrategy().setAfterConvertValidator(new Jsr303BeanValidator(Person.class, "email"));
 +
</source>
 +
 +
You can write :
 +
 +
<source lang="java" >
 +
UpdateValueStrategy updateValueStrategy = Jsr303UpdateValueStrategyFactory.create(Person.class, "email");
 +
</source>
 +
 +
Here the full code to bind SWT Text with the "email" property of Person instance :
 +
 +
<source lang="java" >
 +
Text emailText = ....
 +
Person model = ...
 +
IObservableValue swtEmailTextObservableValue = SWTObservables.observeText(emailText, SWT.Modify);
 +
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
 +
dataBindingContext.bindValue(
 +
swtEmailTextObservableValue,
 +
modelEmailObserveValue,
 +
Jsr303UpdateValueStrategyFactory.create(Person.class, "email"), null);
 +
</source>
 +
 +
==== Use Jsr303BeansUpdateValueStrategyFactory ====
 +
 +
If you are using PojoObservables or BeansObservable, you can simplify more code, where you can avoid setting the Person.class and "email"to create teh well UpdateValueStrategy. When you do :
 +
 +
<source lang="java" >
 +
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email")
 +
</source>
 +
 +
You can know the Class type and the property name by using the IObservableValue. That's why you can simplify your code if you are using PojoObservables or BeansObservables by creating
 +
an instanceof of UpdateValueStrategy configured with JSR-303 by using information of IObservableValue with Jsr303BeansUpdateValueStrategyFactory like this :
 +
 +
<source lang="java" >
 +
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
 +
UpdateValueStrategy updateValueStrategy = Jsr303BeansUpdateValueStrategyFactory .create(modelEmailObserveValue);
 +
</source>
 +
 +
Here the full code to bind SWT Text with the "email" property of Person instance :
 +
 +
<source lang="java" >
 +
Text emailText = ....
 +
Person model = ...
 +
IObservableValue swtEmailTextObservableValue = SWTObservables.observeText(emailText, SWT.Modify);
 +
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
 +
dataBindingContext.bindValue(
 +
swtEmailTextObservableValue,
 +
modelEmailObserveValue,
 +
Jsr303BeansUpdateValueStrategyFactory .create(modelEmailObserveValue), null);
 
</source>
 
</source>
  

Revision as of 08:26, 28 October 2011

Target

Work is underway to support JSR-303 Bean Validation with JFace Databinding Validators. This support was created after reading the Validating JFace Databinding with JSR-303 article.

You can find several plug-in projects from JSR-303 XDocReport Git which provides JSR-303 support for JFace Databinding Validators:

  • 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).

JSR-303 support for JFace Databinding Validators

JSR-303 Overview

@Annotations for JSR-303

JSR-303 Bean Validation gives you the capability to declare with annotation your validation constraints in your Java Pojo model. Here an example with Person class to set validation constraints:

  • "name" property as required.
  • "email" property as email pattern
package org.eclipse.core.databinding.validation.jsr303.samples.model;
 
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
 
public class Person {
 
	@Size(min = 1)
	private String name;
 
	@Size(min = 1)
	@Pattern(regexp = ".+@.+\\.[a-z]+")
	private String email;
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public String getEmail() {
		return email;
	}
 
	public void setEmail(String email) {
		this.email = email;
	}
}

Those validation constraints can be used in any context :

  • UI form could display errors when constraints are not respected. Ex : UI Text field email doesn't contains a well formatted email.
  • ORM like Hibernate can use thoses constraints validation when Pojo model must be saved in the Database.

So JSR-303 gives a commons means to declare your constraint validation that you can used in several context of your application (in your UI form, in your DAO when Pojo must be saved, etc....)

Validator API for JSR-303

JSR-303 Bean Validation provides an API to validate property, value by using JSR-303 constraints validation declared with annotations. Here a sample code to validate the value "XXX" by using the annotations declared in the "email" property of the Person class :

...
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
...
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Set<ConstraintViolation<Person>> violations = factory.getValidator().validateValue(Person.class, "email", "XXX");
for (ConstraintViolation<Person> violation : violations) {
  System.err.println(violation.getMessage());
}

NOTE: this code works only if there is in the ClassPath an implementation of JSR-303 Bean Validation. If you have not an implementation, you will have this error :

Exception in thread "main" javax.validation.ValidationException: Unable to find a default provider
	at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:264)
	at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:111)

Otherwise, with Apache implementation, teh console will display:

must match the following regular expression: .+@.+\.[a-z]+

Validator Implementation for JSR-303

JSR-303 Bean Validation provides an API but not an implementation. To execute validation with JSR-303 you need JSR-303 implementation. It exists several implementation like:

Provided samples with JFace Databinding support for JSR-303 use Hibernate Validator and Apache Bean Validation.

JSR-303 JFace Databinding Validator Overview

JFace Databinding Validator support for JSR-303 provides the org.eclipse.core.databinding.validation.jsr303.Jsr303BeanValidator an implementation of org.eclipse.core.databinding.validation.IValidator which uses Validator API for JSR-303.

Create Jsr303BeanValidator

If you wish create a JFace Databinding Validator to validate "email" property of the Person class :

public class Person {
 
  ...
  @Size(min = 1)
  @Pattern(regexp = ".+@.+\\.[a-z]+")
  private String email;
  ...
}

You can do that :

...
import org.eclipse.core.databinding.validation.jsr303;
import org.eclipse.core.databinding.validation.IValidator;
...
 
IValidator validator = new Jsr303BeanValidator(Person.class, "email");

Use Jsr303BeanValidator

At this step you can use the validator in your DatabindingContext by creating an instanceof of UpdateValueStrategy  :

IValidator validator = new Jsr303BeanValidator(Person.class, "email");
UpdateValueStrategy updateValueStrategy = new UpdateValueStrategy().setAfterConvertValidator(validator);

Here the full code to bind SWT Text with the "email" property of Person instance :

Text emailText = ....
Person model = ...
IObservableValue swtEmailTextObservableValue = SWTObservables.observeText(emailText, SWT.Modify);
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
dataBindingContext.bindValue(
		swtEmailTextObservableValue,
		modelEmailObserveValue,
		new UpdateValueStrategy()
				.setAfterConvertValidator(new Jsr303BeanValidator(
						Person.class, "email")), null);

Use Jsr303UpdateValueStrategyFactory

You can simplify the creation of the JSR-303 UpdateValueStrategy. Instead of doing that:

UpdateValueStrategy updateValueStrategy = new UpdateValueStrategy().setAfterConvertValidator(new Jsr303BeanValidator(Person.class, "email"));

You can write :

UpdateValueStrategy updateValueStrategy = Jsr303UpdateValueStrategyFactory.create(Person.class, "email");

Here the full code to bind SWT Text with the "email" property of Person instance :

Text emailText = ....
Person model = ...
IObservableValue swtEmailTextObservableValue = SWTObservables.observeText(emailText, SWT.Modify);
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
dataBindingContext.bindValue(
		swtEmailTextObservableValue,
		modelEmailObserveValue,
		Jsr303UpdateValueStrategyFactory.create(Person.class, "email"), null);

Use Jsr303BeansUpdateValueStrategyFactory

If you are using PojoObservables or BeansObservable, you can simplify more code, where you can avoid setting the Person.class and "email"to create teh well UpdateValueStrategy. When you do :

IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email")

You can know the Class type and the property name by using the IObservableValue. That's why you can simplify your code if you are using PojoObservables or BeansObservables by creating an instanceof of UpdateValueStrategy configured with JSR-303 by using information of IObservableValue with Jsr303BeansUpdateValueStrategyFactory like this :

IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
UpdateValueStrategy updateValueStrategy = Jsr303BeansUpdateValueStrategyFactory .create(modelEmailObserveValue);

Here the full code to bind SWT Text with the "email" property of Person instance :

Text emailText = ....
Person model = ...
IObservableValue swtEmailTextObservableValue = SWTObservables.observeText(emailText, SWT.Modify);
IObservableValue modelEmailObserveValue = PojoObservables.observeValue(model, "email");
dataBindingContext.bindValue(
		swtEmailTextObservableValue,
		modelEmailObserveValue,
		Jsr303BeansUpdateValueStrategyFactory .create(modelEmailObserveValue), null);

Java main sample

The org.eclipse.core.databinding.validation.jsr303.samples

Eclipse RCP (OSGi context) sample

Back to the top