Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » [Databinding] MultiValidator in RAP Application
[Databinding] MultiValidator in RAP Application [message #489748] Mon, 05 October 2009 18:52 Go to next message
habakuk  is currently offline habakuk Friend
Messages: 32
Registered: October 2009
Member
I'm writing a RAP based application that uses Eclipselink for persistence. I have lot of standard "web forms" that consists of some fields that are filled from the database. After pressing the obligatory save button, the data should be validated and sent to the database. I use the ON_REQUEST policy for the targetToModel UpdateStrategy, so that data only get written to the model when save is pressed. Because I have to validate a time periode (2 date values) I use pretty much the same code as proposed in the Javadoc of MultiValidator. It seems to work, but I noticed that the validator gets called too often. It gets called 3 times when the data is loaded, and 2 times when the data is saved. No idea why. Is there a strategy to make MultValidator called only once when loading/saving. The problem is that my validation might take too much time, because it has to query the database. I cannot validate after every field is updated, I need to validate only after all values are loaded.

Thanks in advance
Re: [Databinding] MultiValidator in RAP Application [message #489767 is a reply to message #489748] Mon, 05 October 2009 19:54 Go to previous messageGo to next message
Matthew Hall is currently offline Matthew HallFriend
Messages: 368
Registered: July 2009
Senior Member
habakuk wrote:
> I'm writing a RAP based application that uses Eclipselink for
> persistence. I have lot of standard "web forms" that consists of some
> fields that are filled from the database. After pressing the obligatory
> save button, the data should be validated and sent to the database. I
> use the ON_REQUEST policy for the targetToModel UpdateStrategy, so that
> data only get written to the model when save is pressed. Because I have
> to validate a time periode (2 date values) I use pretty much the same
> code as proposed in the Javadoc of MultiValidator. It seems to work, but
> I noticed that the validator gets called too often. It gets called 3
> times when the data is loaded, and 2 times when the data is saved. No
> idea why.

Are you creating your MultiValidator before or after all its
dependencies are bound? It is better to create it afterward to minimize
the number of times it has to validate on startup.

> Is there a strategy to make MultValidator called only once
> when loading/saving. The problem is that my validation might take too
> much time, because it has to query the database. I cannot validate after
> every field is updated, I need to validate only after all values are
> loaded.

In this case I would suggest binding in two stages:

target <=> staging <=> model

The staging observables are basically just Writable<Value|List|Set|Map>
instances. Put the simple validators (the ones that don't have to talk
to the database) on the target <=> staging bindings (which should have a
POLICY_CONVERT update policy). The more involved validators should be
attached to the staging <=> model bindings.

The staging <=> model bindings can use the default POLICY_UPDATE update
policy. Now modify your MultiValidator to validate against the staging
observables instead of the target.

You will still have multiple database trips when the MultiValidator's
dependencies are each updated in turn however now you will only incur
those trips once when Ok/Save is clicked instead of on every change.

There was some work going on a while ago to implement asynchronous
validation with MultiValidator [1] and with bindings [2] but for some
reason the work stalled and we never finished it. Something to do with
IProgressMonitor integration I think. If you'd like to take a look into
those bugs and leave your comments maybe we can get those features
moving forward again.

Hope this helps,

Matthew

[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=237857
[2] https://bugs.eclipse.org/bugs/show_bug.cgi?id=233191
Re: [Databinding] MultiValidator in RAP Application [message #489912 is a reply to message #489767] Tue, 06 October 2009 13:22 Go to previous message
habakuk  is currently offline habakuk Friend
Messages: 32
Registered: October 2009
Member
Thanks for your help Matthew. Well I'm already using a 2 stage binding. Because I use RAP with Eclipselink I have to rebind everything after saving data. (This is necessary because after doing a merge JPA returns a new instance of my data object). I think I'm creating the MultiValidator as late as possible. Is there a better way to create the MultiValidator, so that the data that get loaded from the database are not validated? (because I expect them to be valid anyway, it should be sufficient to validate only user entries). I attached my code, maybe there is room for improvement Rolling Eyes

Thank you


private void bindValues() {
    	
    	if (bindingContext != null) {
    		bindingContext.dispose();
    		bindingContext = new DataBindingContext();
    	} 
    	
		bindingContext.bindValue(new RadioGroupObservableValue(radioGroup),
				BeansObservables.observeValue(dv, "typ_id"), 
					new UpdateValueStrategy().setConverter(new DVConverter()), 
					new UpdateValueStrategy().setConverter(new DVModel2TargetConverter()));
			

		IObservableValue guiBeginnObservableValue = SWTObservables.observeSelection(beginn);
		IObservableValue guiEndeObservableValue = SWTObservables.observeSelection(ende);
		
		final IObservableValue middleStartObservableValue = new WritableValue(null, Date.class);
    	        final IObservableValue middleEndObservableValue = new WritableValue(null, Date.class);
    	
         	bindingContext.bindValue(guiBeginnObservableValue, middleStartObservableValue, 
    			new UpdateValueStrategy(UpdateValueStrategy.POLICY_CONVERT), null);
    	        bindingContext.bindValue(guiEndeObservableValue, middleEndObservableValue, 
    			new UpdateValueStrategy(UpdateValueStrategy.POLICY_CONVERT), null);

		IObservableValue modelBeginnObservableValue = BeansObservables.observeValue(dv, "beginn");
		IObservableValue modelEndeObservableValue = BeansObservables.observeValue(dv, "ende");
									
		PeriodValidator periodValidator = new PeriodValidator(middleStartObservableValue, middleEndObservableValue);		
		bindingContext.addValidationStatusProvider(periodValidator);	
		
		bindingContext.bindValue(periodValidator.observeValidatedValue(middleStartObservableValue), modelBeginnObservableValue, null, null);
		bindingContext.bindValue(periodValidator.observeValidatedValue(middleEndObservableValue), modelEndeObservableValue, null, null);
	
    }


class PeriodValidator extends  MultiValidator {

		IObservableValue beginn;
		IObservableValue ende;
		
		public PeriodValidator(IObservableValue beginn, IObservableValue ende) {
			super();
			this.beginn = beginn;
			this.ende = ende;
		}


		@Override
		protected IStatus validate() {
			Date startDate = (Date) this.beginn.getValue();
			Date endDate = (Date) this.ende.getValue();
			System.out.println("PeriodValidator.validate(" + startDate + ", " + endDate + ")");
			if (!startDate.before(endDate)) {
				return ValidationStatus.error("Startdatum muss vor Endedatum sein");
			}
			return ValidationStatus.ok();
		}
		
}




Matthew Hall wrote on Mon, 05 October 2009 15:54
habakuk wrote:
> I'm writing a RAP based application that uses Eclipselink for
> persistence. I have lot of standard "web forms" that consists of some
> fields that are filled from the database. After pressing the obligatory
> save button, the data should be validated and sent to the database. I
> use the ON_REQUEST policy for the targetToModel UpdateStrategy, so that
> data only get written to the model when save is pressed. Because I have
> to validate a time periode (2 date values) I use pretty much the same
> code as proposed in the Javadoc of MultiValidator. It seems to work, but
> I noticed that the validator gets called too often. It gets called 3
> times when the data is loaded, and 2 times when the data is saved. No
> idea why.

Are you creating your MultiValidator before or after all its
dependencies are bound? It is better to create it afterward to minimize
the number of times it has to validate on startup.

> Is there a strategy to make MultValidator called only once
> when loading/saving. The problem is that my validation might take too
> much time, because it has to query the database. I cannot validate after
> every field is updated, I need to validate only after all values are
> loaded.

In this case I would suggest binding in two stages:

target <=> staging <=> model

The staging observables are basically just Writable<Value|List|Set|Map>
instances. Put the simple validators (the ones that don't have to talk
to the database) on the target <=> staging bindings (which should have a
POLICY_CONVERT update policy). The more involved validators should be
attached to the staging <=> model bindings.

The staging <=> model bindings can use the default POLICY_UPDATE update
policy. Now modify your MultiValidator to validate against the staging
observables instead of the target.

You will still have multiple database trips when the MultiValidator's
dependencies are each updated in turn however now you will only incur
those trips once when Ok/Save is clicked instead of on every change.

There was some work going on a while ago to implement asynchronous
validation with MultiValidator [1] and with bindings [2] but for some
reason the work stalled and we never finished it. Something to do with
IProgressMonitor integration I think. If you'd like to take a look into
those bugs and leave your comments maybe we can get those features
moving forward again.

Hope this helps,

Matthew

[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=237857
[2] https://bugs.eclipse.org/bugs/show_bug.cgi?id=233191

Previous Topic:Tree with not necessary Scroll
Next Topic:Need to change font size in ContentAssistant.
Goto Forum:
  


Current Time: Thu Dec 18 16:35:18 GMT 2014

Powered by FUDForum. Page generated in 0.01775 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software