Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » EMF Validation called 4 times for each binding
EMF Validation called 4 times for each binding [message #898398] Thu, 26 July 2012 10:27 Go to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
Hi,

I've set up EMF validation along with an AggregateValidationStatus whose binding context is used to bind several text fields in the UI to the model.

However, when I first open the UI, each bound field causes the validation to be run 4 times. I've got 8 fields on my form at the moment which means the model is validated 32 times which really slows down the page processing!

Any ideas on how to reduce this to just one per field? Or less even!

Here is my code:-

final EMFUpdateValueStrategy updateValueStrategy = new EMFUpdateValueStrategy();
		updateValueStrategy.setAfterGetValidator(new IValidator() {
			@Override
			public IStatus validate(Object value) {
				/* validate the model */
				Diagnostic diagnostic = Diagnostician.INSTANCE.validate(model);

				return BasicDiagnostic.toIStatus(diagnostic);
			}
		});
		
		final AggregateValidationStatus aggregateValidationStatus = new AggregateValidationStatus(
				bindingCtxt, AggregateValidationStatus.MAX_SEVERITY);
		aggregateValidationStatus
				.addValueChangeListener(new IValueChangeListener() {
					@Override
					public void handleValueChange(ValueChangeEvent event) {
						Diagnostic diagnostics = BasicDiagnostic.toDiagnostic(
								updateValueStrategy.validateAfterGet(model))
								.getChildren());

						/*
						 * this is needed or the validation only gets called once
						 */
						aggregateValidationStatus.getValue();
					}
				});
Re: EMF Validation called 4 times for each binding [message #899036 is a reply to message #898398] Mon, 30 July 2012 09:54 Go to previous messageGo to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
Anyone?
Re: EMF Validation called 4 times for each binding [message #899047 is a reply to message #899036] Mon, 30 July 2012 10:55 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

I suggest identifying where the needless repetition comes from.

For this I often take a screen shot of the Debug stack so that I can
compare the next one to see where the deviation is.

It might be that you have a double hierarchy traversal. i.e. An outer
loop over all objects, and an inner child descent per object.

If the worst comes to the worst you can put a timestamp object in the
context map and avoid repetition at the same timestamp.

Regards

Ed Willink


On 30/07/2012 10:54, Simon Barnett wrote:
> Anyone?
Re: EMF Validation called 4 times for each binding [message #899181 is a reply to message #898398] Mon, 30 July 2012 21:23 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Did you printed the ValueChangeEvent event content?

Tom

Am 26.07.12 12:27, schrieb Simon Barnett:
> Hi,
>
> I've set up EMF validation along with an AggregateValidationStatus whose
> binding context is used to bind several text fields in the UI to the model.
>
> However, when I first open the UI, each bound field causes the
> validation to be run 4 times. I've got 8 fields on my form at the moment
> which means the model is validated 32 times which really slows down the
> page processing!
>
> Any ideas on how to reduce this to just one per field? Or less even!
>
> Here is my code:-
>
> final EMFUpdateValueStrategy updateValueStrategy = new
> EMFUpdateValueStrategy();
> updateValueStrategy.setAfterGetValidator(new IValidator() {
> @Override
> public IStatus validate(Object value) {
> /* validate the model */
> Diagnostic diagnostic =
> Diagnostician.INSTANCE.validate(model);
>
> return BasicDiagnostic.toIStatus(diagnostic);
> }
> });
>
> final AggregateValidationStatus aggregateValidationStatus = new
> AggregateValidationStatus(
> bindingCtxt, AggregateValidationStatus.MAX_SEVERITY);
> aggregateValidationStatus
> .addValueChangeListener(new IValueChangeListener() {
> @Override
> public void handleValueChange(ValueChangeEvent event) {
> Diagnostic diagnostics =
> BasicDiagnostic.toDiagnostic(
>
> updateValueStrategy.validateAfterGet(model))
> .getChildren());
>
> /*
> * this is needed or the validation only gets
> called once
> */
> aggregateValidationStatus.getValue();
> }
> });
>
Re: EMF Validation called 4 times for each binding [message #899274 is a reply to message #899181] Tue, 31 July 2012 10:08 Go to previous messageGo to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
Thanks guys. I did think to look through the ValueChangeEvent each time but they seem to be fairly similar with the only difference being the dependencies array that they contain - but I'm not sure what this is for or why it's changing.

As for internal loops etc. I pasted my code above - it's all fairly straight-forward I think - and no confusing loops.

It looks to me as if the call to getValue() at the end of that method causes the listener to trigger a few times but I've no idea why.
Re: EMF Validation called 4 times for each binding [message #899305 is a reply to message #899274] Tue, 31 July 2012 12:33 Go to previous messageGo to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
OK, I figured out that it wasn't the dependencies after all - it's related to the initial bindings.

I have a table in the master section which lists items and when the editor first fires up, it binds the fields (mainly text fields) in the details section to the selected item in the master table.
This binding is done like this:-

IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify);

		IObservableValue uiObs = textProp.observeDelayed(400, textField);
		IObservableValue modelObs;

		if (object instanceof IObservableValue) {
			modelObs = EMFEditProperties.value(domain, feature).observeDetail(
					(IObservableValue) object);
		} else {
			modelObs = EMFEditProperties.value(domain, feature).observe(object);
		}

		binding = bindingCtxt.bindValue(uiObs, modelObs);


This binding causes the ValueChange event to be fired 4 times - so if I have 6 text fields bound then I get 24 ValueChangeEvents.

Once the initial binding has been done, if i then change the value of any one of those text fields in the details section, I only get one ValueChangeEvent.

So it's that first binding that's causing the extra change events. Any idea why that might be?
Re: EMF Validation called 4 times for each binding [message #899475 is a reply to message #899305] Wed, 01 August 2012 05:44 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Not really. bindValue will initially force an model => target update I
guess to work around the problem you should create your
aggregateValidationStatus after the initial binding is done.

Tom

Am 31.07.12 14:33, schrieb Simon Barnett:
> OK, I figured out that it wasn't the dependencies after all - it's
> related to the initial bindings.
>
> I have a table in the master section which lists items and when the
> editor first fires up, it binds the fields (mainly text fields) in the
> details section to the selected item in the master table.
> This binding is done like this:-
>
>
> IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify);
>
> IObservableValue uiObs = textProp.observeDelayed(400, textField);
> IObservableValue modelObs;
>
> if (object instanceof IObservableValue) {
> modelObs = EMFEditProperties.value(domain,
> feature).observeDetail(
> (IObservableValue) object);
> } else {
> modelObs = EMFEditProperties.value(domain,
> feature).observe(object);
> }
>
> binding = bindingCtxt.bindValue(uiObs, modelObs);
>
>
> This binding causes the ValueChange event to be fired 4 times - so if I
> have 6 text fields bound then I get 24 ValueChangeEvents.
>
> Once the initial binding has been done, if i then change the value of
> any one of those text fields in the details section, I only get one
> ValueChangeEvent.
>
> So it's that first binding that's causing the extra change events. Any
> idea why that might be?
Re: EMF Validation called 4 times for each binding [message #899533 is a reply to message #899475] Wed, 01 August 2012 10:46 Go to previous messageGo to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
No Message Body

[Updated on: Wed, 01 August 2012 10:47]

Report message to a moderator

Re: EMF Validation called 4 times for each binding [message #899536 is a reply to message #899533] Wed, 01 August 2012 10:55 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Why is this not a master-detail-binding?

Tom

Am 01.08.12 12:46, schrieb Simon Barnett:
> Ah yes, I could do that - but the problem is, one of my pages has a
> table on the master section with bound fields on the right. So each time
> the user selects a different table item, the bindValue is redone so that
> the details section can show the new values.
Re: EMF Validation called 4 times for each binding [message #899540 is a reply to message #899536] Wed, 01 August 2012 11:02 Go to previous messageGo to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
OK, this sounds like I might have done something in a non-standard way then.

I have bound the master side of the page to the collection of objects that I want it to represent. And when the user selects an item in this table, it reacts to the SelectionChanged event and rebinds the details side to show the new values.

Is there a better way? It sounds like it.
Re: EMF Validation called 4 times for each binding [message #899558 is a reply to message #899540] Wed, 01 August 2012 12:24 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
That's not needed.

The general approach here is:

EMFDatabindingContext dbc = ....
TableViewer v = ....
IObservableValue sel = ViewerProperties.singleSelection().observe(v);


Text t = ....
dbc.bindValue(
WidgetProperties.text(SWT.Modify).observeDelayed(t),
EMFEditProperties.value(....).observeDetail(sel)
);

Tom

Am 01.08.12 13:02, schrieb Simon Barnett:
> OK, this sounds like I might have done something in a non-standard way
> then.
>
> I have bound the master side of the page to the collection of objects
> that I want it to represent. And when the user selects an item in this
> table, it reacts to the SelectionChanged event and rebinds the details
> side to show the new values.
>
> Is there a better way? It sounds like it.
Re: EMF Validation called 4 times for each binding [message #899591 is a reply to message #899558] Wed, 01 August 2012 14:25 Go to previous messageGo to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
Ah, I see - well I've got that working so thanks for that.

But in order to get the bindings to occur before the AggregateValidationContext is created, I need to change things around a bit.

The problem is that the page that contains the table/text fields is not the initial page so it's createFormContent() method isn't called until the user selects the page, by which time it's too late.

Do you know of a way around this? I suppose I'll need to try and find a way to create all of the pages form content before the pages are actually selected.
Re: EMF Validation called 4 times for each binding [message #899637 is a reply to message #899591] Wed, 01 August 2012 15:59 Go to previous messageGo to next message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
Argh, I've nearly got it all working now - except I can't get a table to bind properly.

So as well as some text fields and combos, I have a table in the details section which should be bound to a collection within the selected item in the master table.

I've currently got the binding written like this:-

IObservableList list = EMFObservables.observeDetailList(
				Realm.getDefault(),
				EMFProperties.value(ModelPackage.Literals.MODEL__ITEMS).observeDetail(sel),
				detailsTableFeature);
		
		ViewerSupport.bind(detailsTableViewer, list,
				EMFProperties.values(columnFeatures));


But that doesn't work - the details table is empty.

However, if I use the following code:-

IObservableList list = EMFObservables.observeList(Realm.getDefault(),
				model.getItems().get(1),
				detailsTableFeature);*/


it will show the correct list of sub-items for item 1 in the model.

So I'm close - I just need to know what the 2nd argument to observeDetailList() should look like.
Re: EMF Validation called 4 times for each binding [message #899725 is a reply to message #899637] Thu, 02 August 2012 06:29 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Am 01.08.12 17:59, schrieb Simon Barnett:
> Argh, I've nearly got it all working now - except I can't get a table to
> bind properly.
>
> So as well as some text fields and combos, I have a table in the details
> section which should be bound to a collection within the selected item
> in the master table.
>
> I've currently got the binding written like this:-
>
> IObservableList list = EMFObservables.observeDetailList(
> Realm.getDefault(),
>
> EMFProperties.value(ModelPackage.Literals.MODEL__ITEMS).observeDetail(sel),
> detailsTableFeature);
>
> ViewerSupport.bind(detailsTableViewer, list,
> EMFProperties.values(columnFeatures));
>

IObservableList list =
EMFProperties.list(ModelPackage.Literals.MODEL__ITEMS).observeDetail(sel);

ViewerSupport.bind(detailsTableViewer,
list,EMFProperties.values(columnFeatures));

*You don't use EMFObservables any more at all*

Tom
Re: EMF Validation called 4 times for each binding [message #899751 is a reply to message #899725] Thu, 02 August 2012 08:18 Go to previous message
Simon Barnett is currently offline Simon BarnettFriend
Messages: 28
Registered: July 2012
Junior Member
Ah, thanks Tom - it turns out I'd tried that earlier but it just caused an error about the columns not having a label provider. But when I looked at the code again this morning, I'd accidentally moved the column setup code to below the bind code - doh!

Thanks a lot for your invaluable help on this one. Much appreciated!
Previous Topic:[CDO/Hibernate] Can Hibernate Validation be used with CDO/Teneo?
Next Topic:[XCore] Referning to <Package>Package.Literals.<Class-Reference>
Goto Forum:
  


Current Time: Thu Mar 28 09:55:14 GMT 2024

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

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

Back to the top