Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO databinding]
[CDO databinding] [message #510385] Wed, 27 January 2010 07:26 Go to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Hi,

I'm using EMF, CDO and databinding. I have a master detail scenario with
a viewer and a detail part. I just was testing what happens when I have
opened the application twice to see how the notification and update runs.

Now I ran into the problem, that when I delete an entry in Appl1, it
crashes in Appl2 when the viewer is refreshed from the
ObservableListContentProvider. Here the stack trace:


org.eclipse.core.runtime.AssertionFailedException: null argument:
at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
at
org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
at
org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
at
org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
at
org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
at
org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
at
org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
at
org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
at
org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
at
org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
at
org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
at
org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
at
org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
at
org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
at
org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
at
org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
at
org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
at
org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
at
org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
at
org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
at
org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
at
org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
at
org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
at
org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
at
org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
at
org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
at
org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
....

So it seems that a "null" object is delivered to the viewer. I tried to
track it down further and ended up in
EMFListPropertyListener#notifyChanged(Notification). In the switch at
case "Notification.REMOVE", a list diff is created with
Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(), false,
msg.getOldValue())). Now I guess the problem is that msg.getOldValue()
returns null!

I checked that also in Appl1 (in the same CDOView that the element is
deleted) and saw that msg.getOldValue() returns the deleted object.

Is this actually a bug? If not then IMHO CDO and databinding is not
usable as is.

Cheers.
--Thomas
Re: [CDO databinding] [message #510386 is a reply to message #510385] Wed, 27 January 2010 07:26 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Sorry my subject was a bit poor :-(
I just forgot to type further...
Hmm... Should I post a new one with correct subject?

Thomas Kowatsch schrieb:
> Hi,
>
> I'm using EMF, CDO and databinding. I have a master detail scenario with
> a viewer and a detail part. I just was testing what happens when I have
> opened the application twice to see how the notification and update runs.
>
> Now I ran into the problem, that when I delete an entry in Appl1, it
> crashes in Appl2 when the viewer is refreshed from the
> ObservableListContentProvider. Here the stack trace:
>
>
> org.eclipse.core.runtime.AssertionFailedException: null argument:
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
> at
> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
>
> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
> at
> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
>
> at
> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
>
> at
> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>
> at
> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>
> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
> at
> org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
> at
> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
>
> at
> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
>
> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
> at
> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
>
> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
> ...
>
> So it seems that a "null" object is delivered to the viewer. I tried to
> track it down further and ended up in
> EMFListPropertyListener#notifyChanged(Notification). In the switch at
> case "Notification.REMOVE", a list diff is created with
> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(), false,
> msg.getOldValue())). Now I guess the problem is that msg.getOldValue()
> returns null!
>
> I checked that also in Appl1 (in the same CDOView that the element is
> deleted) and saw that msg.getOldValue() returns the deleted object.
>
> Is this actually a bug? If not then IMHO CDO and databinding is not
> usable as is.
>
> Cheers.
> --Thomas
Re: [CDO databinding] [message #510392 is a reply to message #510385] Wed, 27 January 2010 12:30 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

I can only comment on the DB side of the story and I can't see us doing
something wrong nor illegal. Interesting enough I've never hit this
problem myself with CDO and Databinding.

I'm not even sure we could fix this because this would require us to
keep a copy of the original list and diff it with the new one. So I hope
Eike can comment on this.

Out of curiosity is the detail-list a containment or no containment list?

If CDO is not sending the removed element one would run into same
problem whether DB is used or not I guess BTW.

Tom

Am 27.01.10 13:16, schrieb Thomas Kowatsch:
> Hi,
>
> I'm using EMF, CDO and databinding. I have a master detail scenario with
> a viewer and a detail part. I just was testing what happens when I have
> opened the application twice to see how the notification and update runs.
>
> Now I ran into the problem, that when I delete an entry in Appl1, it
> crashes in Appl2 when the viewer is refreshed from the
> ObservableListContentProvider. Here the stack trace:
>
>
> org.eclipse.core.runtime.AssertionFailedException: null argument:
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
> at
> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
>
> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
> at
> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
>
> at
> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
>
> at
> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>
> at
> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>
> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
> at
> org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
> at
> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
>
> at
> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
>
> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
> at
> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
>
> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
> ...
>
> So it seems that a "null" object is delivered to the viewer. I tried to
> track it down further and ended up in
> EMFListPropertyListener#notifyChanged(Notification). In the switch at
> case "Notification.REMOVE", a list diff is created with
> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(), false,
> msg.getOldValue())). Now I guess the problem is that msg.getOldValue()
> returns null!
>
> I checked that also in Appl1 (in the same CDOView that the element is
> deleted) and saw that msg.getOldValue() returns the deleted object.
>
> Is this actually a bug? If not then IMHO CDO and databinding is not
> usable as is.
>
> Cheers.
> --Thomas
Re: [CDO databinding] [message #510401 is a reply to message #510392] Wed, 27 January 2010 07:54 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Tom Schindl schrieb:
> Hi,
>
> I can only comment on the DB side of the story and I can't see us doing
> something wrong nor illegal. Interesting enough I've never hit this
> problem myself with CDO and Databinding.
>
> I'm not even sure we could fix this because this would require us to
> keep a copy of the original list and diff it with the new one. So I hope
> Eike can comment on this.
I think a colleague alreday was talking to Eike and he said that you
might give a good answer :-)
>
> Out of curiosity is the detail-list a containment or no containment list?
Hmmm. I you want to know in which list the element is deleted, then it
is a containment list. Like Organisation has a list of Users and I
delete a User. The User list is diaplayed in the viewer...
>
> If CDO is not sending the removed element one would run into same
> problem whether DB is used or not I guess BTW.
Yes, if one uses Notification#getOldValue() .... but one obviously has to?
>
> Tom
>
Re: [CDO databinding] [message #510404 is a reply to message #510401] Wed, 27 January 2010 12:58 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Am 27.01.10 13:46, schrieb Thomas Kowatsch:
> Tom Schindl schrieb:
>> Hi,
>>
>> I can only comment on the DB side of the story and I can't see us doing
>> something wrong nor illegal. Interesting enough I've never hit this
>> problem myself with CDO and Databinding.
>>
>> I'm not even sure we could fix this because this would require us to
>> keep a copy of the original list and diff it with the new one. So I hope
>> Eike can comment on this.
> I think a colleague alreday was talking to Eike and he said that you
> might give a good answer :-)

As said I guess we (DB) can't do anything against this because CDO usage
of CDO should be transparent. I'm going to look into this with Eike when
he's available.

>>
>> Out of curiosity is the detail-list a containment or no containment list?
> Hmmm. I you want to know in which list the element is deleted, then it
> is a containment list. Like Organisation has a list of Users and I
> delete a User. The User list is diaplayed in the viewer...

Strange because that's been exactly the use case in my example
applications as well.

Can you try to create a plain CDO-Test-Case which demonstrates that such
a change notification holds a NULL-Value?

>>
>> If CDO is not sending the removed element one would run into same
>> problem whether DB is used or not I guess BTW.
> Yes, if one uses Notification#getOldValue() .... but one obviously has to?

I don't see another possibility beside going the brute force way of
doing a refresh() on the viewer instead of a add/remove so you could
probably fix this in the meatime by crafting your own content-provider
issuing a refresh() is the diff element is NULL.

Tom
Re: [CDO databinding] [message #510409 is a reply to message #510404] Wed, 27 January 2010 13:16 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Tom Schindl schrieb:
> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>> Tom Schindl schrieb:
<snip>
>
> Strange because that's been exactly the use case in my example
> applications as well.
>
I know. But the problem occurs only if you have two different CDO
sessions. In the session in which you remove the object,
Notification#getOldValue() is not null! In any other session it is null!
Did you ever test it using two instances of your project manager?

-- Thomas
Re: [CDO databinding] [message #510411 is a reply to message #510409] Wed, 27 January 2010 08:36 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Thomas Kowatsch schrieb:
> Tom Schindl schrieb:
>> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>>> Tom Schindl schrieb:
> <snip>
>>
>> Strange because that's been exactly the use case in my example
>> applications as well.
>>
> I know. But the problem occurs only if you have two different CDO
> sessions. In the session in which you remove the object,
> Notification#getOldValue() is not null! In any other session it is null!
> Did you ever test it using two instances of your project manager?

Hmmm. Your example just uses a XMI Resource, so you cannot really test
it, as you need a database on which you open two session or run two
project admin applications on. Also I could't see a possibility to
remove a project....

>
> -- Thomas
Re: [CDO databinding] [message #510420 is a reply to message #510411] Wed, 27 January 2010 13:52 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
I'm talking about other example applications I wrote a while back e.g.
my SoccerAdministration and there worked with multiple sessions, ... .

Tom

Am 27.01.10 14:28, schrieb Thomas Kowatsch:
> Thomas Kowatsch schrieb:
>> Tom Schindl schrieb:
>>> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>>>> Tom Schindl schrieb:
>> <snip>
>>>
>>> Strange because that's been exactly the use case in my example
>>> applications as well.
>>>
>> I know. But the problem occurs only if you have two different CDO
>> sessions. In the session in which you remove the object,
>> Notification#getOldValue() is not null! In any other session it is null!
>> Did you ever test it using two instances of your project manager?
>
> Hmmm. Your example just uses a XMI Resource, so you cannot really test
> it, as you need a database on which you open two session or run two
> project admin applications on. Also I could't see a possibility to
> remove a project....
>
>>
>> -- Thomas
Re: [CDO databinding] [message #510422 is a reply to message #510420] Wed, 27 January 2010 13:58 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Tom Schindl schrieb:
> I'm talking about other example applications I wrote a while back e.g.
> my SoccerAdministration and there worked with multiple sessions, ... .

Ahhh. Sorry....
Re: [CDO databinding] [message #510456 is a reply to message #510404] Wed, 27 January 2010 15:07 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Tom Schindl schrieb:
> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>> Tom Schindl schrieb:
>
> Can you try to create a plain CDO-Test-Case which demonstrates that such
> a change notification holds a NULL-Value?
>

The behaviour is stated in the javadoc of CDODeltaNotification:

/**
* This class behaves like the usual EMF Notification except for the
following:
* <ul>
* <li>It doesn't provide the old value, only the new index or new value.
* <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that
{@link Collection#clear() clear()} was called.
* <li>{@link Notification#Add_MANY Add_MANY} is not used.
* </ul>
*
* @since 2.0
* @author Simon McDuff
Re: [CDO databinding] [message #510461 is a reply to message #510456] Wed, 27 January 2010 15:16 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Ok thanks for the info I'll try to talk with Eike about this not sure
what the conclusion should be though.

Tom

Am 27.01.10 16:07, schrieb Thomas Kowatsch:
> Tom Schindl schrieb:
>> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>>> Tom Schindl schrieb:
>>
>> Can you try to create a plain CDO-Test-Case which demonstrates that such
>> a change notification holds a NULL-Value?
>>
>
> The behaviour is stated in the javadoc of CDODeltaNotification:
>
> /**
> * This class behaves like the usual EMF Notification except for the
> following:
> * <ul>
> * <li>It doesn't provide the old value, only the new index or new value.
> * <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that
> {@link Collection#clear() clear()} was called.
> * <li>{@link Notification#Add_MANY Add_MANY} is not used.
> * </ul>
> *
> * @since 2.0
> * @author Simon McDuff
Re: [CDO databinding] [message #510481 is a reply to message #510461] Wed, 27 January 2010 15:32 Go to previous messageGo to next message
Erwin Betschart is currently offline Erwin BetschartFriend
Messages: 4
Registered: July 2009
Junior Member
This is a multi-part message in MIME format.
--------------070806060605050201070104
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Hi Tom

I work with Thomas...

I wrote a CDO test case which shows that the old value is null (fails if
not null). In case you still need one.

Cheers

Erwin

Tom Schindl schrieb:
> Ok thanks for the info I'll try to talk with Eike about this not sure
> what the conclusion should be though.
>
> Tom
>
> Am 27.01.10 16:07, schrieb Thomas Kowatsch:
>> Tom Schindl schrieb:
>>> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>>>> Tom Schindl schrieb:
>>> Can you try to create a plain CDO-Test-Case which demonstrates that such
>>> a change notification holds a NULL-Value?
>>>
>> The behaviour is stated in the javadoc of CDODeltaNotification:
>>
>> /**
>> * This class behaves like the usual EMF Notification except for the
>> following:
>> * <ul>
>> * <li>It doesn't provide the old value, only the new index or new value.
>> * <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that
>> {@link Collection#clear() clear()} was called.
>> * <li>{@link Notification#Add_MANY Add_MANY} is not used.
>> * </ul>
>> *
>> * @since 2.0
>> * @author Simon McDuff
>


--------------070806060605050201070104
Content-Type: text/x-java;
name="CDONotificationTest.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="CDONotificationTest.java"

/**
* Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.cdo.tests;

import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;

import java.util.ArrayList;
import java.util.List;

public class CDONotificationTest extends AbstractCDOTest
{

public void test2SessionOldValueNull() throws Exception
{
msg("Opening 2 sessions");
final CDOSession session1 = openModel1Session();
final CDOSession session2 = openModel1Session();

// ************************************************************ * //

msg("Creating company");
Company companyA = getModel1Factory().createCompany();
TestAdapter testAdapter = new TestAdapter();
msg("Opening transaction");
CDOTransaction transaction = session1.openTransaction();

CDOResource resA = transaction.createResource("/resA");
resA.getContents().add(companyA);

msg("Committing initial model");
transaction.commit();

msg("Opening view on session 2");
CDOView view2 = session2.openView();

view2.options().addChangeSubscriptionPolicy(CDOAdapterPolicy .ALL);

CDOResource resA2 = view2.getResource("/resA");
resA2.eAdapters().add(testAdapter);

msg("Removing company");
// Initial model created.
resA.getContents().remove(0);

// For REMOVE_MANY
// resA.getContents().clear();

msg("Committing remove");
transaction.commit();

Thread.sleep(1000);

assertEquals(1, testAdapter.getNotifications().size());

Notification notification = testAdapter.getNotifications().get(0);

assertNull(notification.getOldValue());
}

/**
* @author Simon McDuff
*/
private static class TestAdapter implements Adapter
{
private List<Notification> notifications = new ArrayList<Notification>();

public TestAdapter()
{
}

public Notifier getTarget()
{
return null;
}

public List<Notification> getNotifications()
{
return notifications;
}

public boolean isAdapterForType(Object type)
{
return false;
}

public void notifyChanged(Notification notification)
{
notifications.add(notification);
}

public void setTarget(Notifier newTarget)
{
}
}
}

--------------070806060605050201070104--
Re: [CDO databinding] [message #510490 is a reply to message #510481] Wed, 27 January 2010 15:54 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi Erwin,

Would be great to have one - it will make it easier to work on a
solution to this problem (I hope we can find one) because having a
CDO-capable Databinding implementation is a must for my own future projects.

Tom

Am 27.01.10 16:32, schrieb Erwin Betschart:
> Hi Tom
>
> I work with Thomas...
>
> I wrote a CDO test case which shows that the old value is null (fails if
> not null). In case you still need one.
>
> Cheers
>
> Erwin
>
> Tom Schindl schrieb:
>> Ok thanks for the info I'll try to talk with Eike about this not sure
>> what the conclusion should be though.
>>
>> Tom
>>
>> Am 27.01.10 16:07, schrieb Thomas Kowatsch:
>>> Tom Schindl schrieb:
>>>> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>>>>> Tom Schindl schrieb:
>>>> Can you try to create a plain CDO-Test-Case which demonstrates that
>>>> such
>>>> a change notification holds a NULL-Value?
>>>>
>>> The behaviour is stated in the javadoc of CDODeltaNotification:
>>>
>>> /**
>>> * This class behaves like the usual EMF Notification except for the
>>> following:
>>> * <ul>
>>> * <li>It doesn't provide the old value, only the new index or new
>>> value.
>>> * <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that
>>> {@link Collection#clear() clear()} was called.
>>> * <li>{@link Notification#Add_MANY Add_MANY} is not used.
>>> * </ul>
>>> *
>>> * @since 2.0
>>> * @author Simon McDuff
>>
>
Re: [CDO databinding] [message #510506 is a reply to message #510490] Wed, 27 January 2010 16:49 Go to previous messageGo to next message
Erwin Betschart is currently offline Erwin BetschartFriend
Messages: 4
Registered: July 2009
Junior Member
Hi Tom


I've attached the test case in the last post ;-)

Cheers

Erwin

Tom Schindl schrieb:
> Hi Erwin,
>
> Would be great to have one - it will make it easier to work on a
> solution to this problem (I hope we can find one) because having a
> CDO-capable Databinding implementation is a must for my own future projects.
>
> Tom
>
> Am 27.01.10 16:32, schrieb Erwin Betschart:
>> Hi Tom
>>
>> I work with Thomas...
>>
>> I wrote a CDO test case which shows that the old value is null (fails if
>> not null). In case you still need one.
>>
>> Cheers
>>
>> Erwin
>>
>> Tom Schindl schrieb:
>>> Ok thanks for the info I'll try to talk with Eike about this not sure
>>> what the conclusion should be though.
>>>
>>> Tom
>>>
>>> Am 27.01.10 16:07, schrieb Thomas Kowatsch:
>>>> Tom Schindl schrieb:
>>>>> Am 27.01.10 13:46, schrieb Thomas Kowatsch:
>>>>>> Tom Schindl schrieb:
>>>>> Can you try to create a plain CDO-Test-Case which demonstrates that
>>>>> such
>>>>> a change notification holds a NULL-Value?
>>>>>
>>>> The behaviour is stated in the javadoc of CDODeltaNotification:
>>>>
>>>> /**
>>>> * This class behaves like the usual EMF Notification except for the
>>>> following:
>>>> * <ul>
>>>> * <li>It doesn't provide the old value, only the new index or new
>>>> value.
>>>> * <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that
>>>> {@link Collection#clear() clear()} was called.
>>>> * <li>{@link Notification#Add_MANY Add_MANY} is not used.
>>>> * </ul>
>>>> *
>>>> * @since 2.0
>>>> * @author Simon McDuff
>
Re: [CDO databinding] [message #510671 is a reply to message #510385] Thu, 28 January 2010 09:46 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------060305060907050103000402
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

Hey Guys,

I was out of office, so I chime in late. More comments below...

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper




Thomas Kowatsch schrieb:
> Hi,
>
> I'm using EMF, CDO and databinding. I have a master detail scenario
> with a viewer and a detail part. I just was testing what happens when
> I have opened the application twice to see how the notification and
> update runs.
>
> Now I ran into the problem, that when I delete an entry in Appl1, it
> crashes in Appl2 when the viewer is refreshed from the
> ObservableListContentProvider. Here the stack trace:
>
>
> org.eclipse.core.runtime.AssertionFailedException: null argument:
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
> at
> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
>
> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
> at
> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
>
> at
> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
>
> at
> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>
> at
> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>
> at
> org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
> at
> org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
> at
> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
>
> at
> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
>
> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
> at
> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
>
> at
> org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
> at
> org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
> ....
>
> So it seems that a "null" object is delivered to the viewer. I tried
> to track it down further and ended up in
> EMFListPropertyListener#notifyChanged(Notification). In the switch at
> case "Notification.REMOVE",
Shouldn't that be REMOVE_MANY?

> a list diff is created with
> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(),
> false, msg.getOldValue())). Now I guess the problem is that
> msg.getOldValue() returns null!
As per JavaDoc in CDODeltaNotification CDO does not provide old values:
| * This *class *behaves like the usual EMF Notification except *for *the following:
* <ul>
* <li>It doesn't provide the old value, only the *new *index or *new *value.
* <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that {@link Collection#clear() clear()} was called.
* <li>{@link Notification#Add_MANY Add_MANY} is not used.
* </ul>|


The reason was/is that the old value is usually rarely used and very
expensive to determine and transfer by CDO in advance (i.e. with the
original CommitNotificationRequest). After the original notification it
would be impossible to lazily request it from the server if audfiting is
not enabled in the repository. We *could* discuss an enhancement in the
change subscription options so that there is a third option beside
ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
(needed per object?, etc...) and quite some effort. to implement. Before
we even consider this discussion I'd like to understand what exactly the
old values are used for by data binding.

Is it true that the old values are only used to push some undo
information to a command stack or so? This would IMO be questionable
anyway, because I doubt that changes of a remote user should be undoable
at all. Maybe we some specialized logic in the databinding that treats
CDODeltaNotifications (instanceof check) differently from normal EMF
Notifications. The new values should be set into the UI, but these
changes should not be undoable. Opinions?

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>
> I checked that also in Appl1 (in the same CDOView that the element is
> deleted) and saw that msg.getOldValue() returns the deleted object.
>
> Is this actually a bug? If not then IMHO CDO and databinding is not
> usable as is.
>
> Cheers.
> --Thomas

--------------060305060907050103000402
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hey Guys,<br>
<br>
I was out of office, so I chime in late. More comments below...<br>
<br>
Cheers<br>
/Eike<br>
<br>
----<br>
<a class="moz-txt-link-freetext" href="http://thegordian.blogspot.com">http://thegordian.blogspot.com</a><br>
<a class="moz-txt-link-freetext" href="http://twitter.com/eikestepper">http://twitter.com/eikestepper</a><br>
<br>
<br>
<br>
<br>
Thomas Kowatsch schrieb:
<blockquote cite="mid:hjpaqo$e12$1@build.eclipse.org" type="cite">Hi,
<br>
<br>
I'm using EMF, CDO and databinding. I have a master detail scenario
with a viewer and a detail part. I just was testing what happens when I
have opened the application twice to see how the notification and
update runs.
<br>
<br>
Now I ran into the problem, that when I delete an entry in Appl1, it
crashes in Appl2 when the viewer is refreshed from the
ObservableListContentProvider. Here the stack trace:
<br>
<br>
<br>
org.eclipse.core.runtime.AssertionFailedException: null argument:
<br>


Re: [CDO databinding] [message #510672 is a reply to message #510671] Thu, 28 January 2010 09:50 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Eike Stepper schrieb:
>> a list diff is created with
>> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(),
>> false, msg.getOldValue())). Now I guess the problem is that
>> msg.getOldValue() returns null!
I forgot to mention that we might consider to return an empty list
rather than just null for REMOVE_MANY (ADD_MANY?). That would at least
cure the NPE...

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO databinding] [message #510673 is a reply to message #510409] Thu, 28 January 2010 09:54 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Thomas Kowatsch schrieb:
> I know. But the problem occurs only if you have two different CDO
> sessions. In the session in which you remove the object,
> Notification#getOldValue() is not null! In any other session it is null!
I think we did our best to integrate *remote* changes with the existing
EMF notification mechanism. But we should realize that remote change is
conceptually different from local change, see undo capabilities.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO databinding] [message #510674 is a reply to message #510672] Thu, 28 January 2010 10:11 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33218
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------060402060304030000010502
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

What's been removed or added isn't known?

Eike Stepper wrote:
> Eike Stepper schrieb:
>
>>> a list diff is created with
>>> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(),
>>> false, msg.getOldValue())). Now I guess the problem is that
>>> msg.getOldValue() returns null!
>>>
> I forgot to mention that we might consider to return an empty list
> rather than just null for REMOVE_MANY (ADD_MANY?). That would at least
> cure the NPE...
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>

--------------060402060304030000010502
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
What's been removed or added isn't known?<br>
<br>
Eike Stepper wrote:
<blockquote cite="mid:hjrmli$ode$2@build.eclipse.org" type="cite">
<pre wrap="">Eike Stepper schrieb:
</pre>
<blockquote type="cite">
<blockquote type="cite">
<pre wrap="">a list diff is created with
Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(),
false, msg.getOldValue())). Now I guess the problem is that
msg.getOldValue() returns null!
</pre>
</blockquote>
</blockquote>
<pre wrap=""><!---->I forgot to mention that we might consider to return an empty list
rather than just null for REMOVE_MANY (ADD_MANY?). That would at least
cure the NPE...

Cheers
/Eike

----
<a class="moz-txt-link-freetext" href="http://thegordian.blogspot.com">http://thegordian.blogspot.com</a>
<a class="moz-txt-link-freetext" href="http://twitter.com/eikestepper">http://twitter.com/eikestepper</a>

</pre>
</blockquote>
</body>
</html>

--------------060402060304030000010502--


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [CDO databinding] [message #510675 is a reply to message #510671] Thu, 28 January 2010 10:25 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Eike Stepper schrieb:
<snip>
>> So it seems that a "null" object is delivered to the viewer. I tried
>> to track it down further and ended up in
>> EMFListPropertyListener#notifyChanged(Notification). In the switch at
>> case "Notification.REMOVE",
> Shouldn't that be REMOVE_MANY?
>
Hmm Nope (see also the CDODeltaNotification javadoc below, only when
Collection#clear() is done). When it is just one element removed it ends
up in the REMOVE case where it uses getOldValue().
But REMOVE_MANY also has a potential problem, as getOldValue() should
return null and the listener in EMFListPropertyListener does:

case Notification.REMOVE_MANY: {
Collection< ? > oldValues = (Collection< ? >)msg.getOldValue();
ListDiffEntry[] listDiffEntries = new ListDiffEntry[oldValues.size()];

This will cause a NPE.

>> a list diff is created with
>> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(),
>> false, msg.getOldValue())). Now I guess the problem is that
>> msg.getOldValue() returns null!
> As per JavaDoc in CDODeltaNotification CDO does not provide old values:
> | * This *class *behaves like the usual EMF Notification except *for *the following:
> * <ul>
> * <li>It doesn't provide the old value, only the *new *index or *new *value.
> * <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that {@link Collection#clear() clear()} was called.
> * <li>{@link Notification#Add_MANY Add_MANY} is not used.
> * </ul>|
>
<snip>

-- Thomas
Re: [CDO databinding] [message #510678 is a reply to message #510674] Thu, 28 January 2010 05:32 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Ed Merks schrieb:
> What's been removed or added isn't known?
The *delta* is know on CDO server side (during processing of incoming
commit operations) in all cases. Same is true for the resulting new
values. The whole old values are only known while processing the commit
operation and lost thereafter if auditing is NOT enabled.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO databinding] [message #510682 is a reply to message #510675] Thu, 28 January 2010 10:32 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Thomas Kowatsch schrieb:
> Hmm Nope (see also the CDODeltaNotification javadoc below, only when
> Collection#clear() is done). When it is just one element removed it
> ends up in the REMOVE case where it uses getOldValue().
> But REMOVE_MANY also has a potential problem, as getOldValue() should
> return null and the listener in EMFListPropertyListener does:
>
> case Notification.REMOVE_MANY: {
> Collection< ? > oldValues = (Collection< ? >)msg.getOldValue();
> ListDiffEntry[] listDiffEntries = new ListDiffEntry[oldValues.size()];
>
> This will cause a NPE.
We should fix that by returning at least an empty list. Please file a
bugzilla.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO databinding] [message #510690 is a reply to message #510671] Thu, 28 January 2010 06:02 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
[...]

> The reason was/is that the old value is usually rarely used and very
> expensive to determine and transfer by CDO in advance (i.e. with the
> original CommitNotificationRequest). After the original notification it
> would be impossible to lazily request it from the server if audfiting is
> not enabled in the repository. We *could* discuss an enhancement in the
> change subscription options so that there is a third option beside
> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
> (needed per object?, etc...) and quite some effort. to implement. Before
> we even consider this discussion I'd like to understand what exactly the
> old values are used for by data binding.

Eclipse-Databinding or in this case JFace-Databinding listens to changes
in an ObservableList of Objects and adds/removes them from a JFace-Viewer.

The only other option would be for the JFace-Databinding to refresh the
complete viewers contents which is would decrease performance incredible.

How would you implement an Table/List-UI which updates itself on changes
of a List?

We could ask the JFace-Viewer-Databinding maintainers to add a special
case in their code which leads to a complete refresh if the Diff is
empty or holds an null-value but I guess CDOs behaviour breaks the
API-contract of Eclipse-Databinding.

Probably we should discuss with upstream if they have an API contract
for a modification whose content couldn't be identified.

What I don't completely understand is that the object removed in this
case must be deleted from the local store/list as well (at least in the
use case we see here it must have been on the client).

Tom
Re: [CDO databinding] [message #510692 is a reply to message #510690] Thu, 28 January 2010 06:02 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Tom Schindl schrieb:
> [...]
>
>> The reason was/is that the old value is usually rarely used and very
>> expensive to determine and transfer by CDO in advance (i.e. with the
>> original CommitNotificationRequest). After the original notification it
>> would be impossible to lazily request it from the server if audfiting is
>> not enabled in the repository. We *could* discuss an enhancement in the
>> change subscription options so that there is a third option beside
>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>> (needed per object?, etc...) and quite some effort. to implement. Before
>> we even consider this discussion I'd like to understand what exactly the
>> old values are used for by data binding.
>
> Eclipse-Databinding or in this case JFace-Databinding listens to changes
> in an ObservableList of Objects and adds/removes them from a JFace-Viewer.
>
> The only other option would be for the JFace-Databinding to refresh the
> complete viewers contents which is would decrease performance incredible.
>
> How would you implement an Table/List-UI which updates itself on changes
> of a List?
>
> We could ask the JFace-Viewer-Databinding maintainers to add a special
> case in their code which leads to a complete refresh if the Diff is
> empty or holds an null-value but I guess CDOs behaviour breaks the
> API-contract of Eclipse-Databinding.
>
> Probably we should discuss with upstream if they have an API contract
> for a modification whose content couldn't be identified.
>
> What I don't completely understand is that the object removed in this
> case must be deleted from the local store/list as well (at least in the
> use case we see here it must have been on the client).

Isn't it deleted by the index which is deliverd in the Notification?

>
> Tom
Re: [CDO databinding] [message #510696 is a reply to message #510682] Thu, 28 January 2010 11:13 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

https://bugs.eclipse.org/bugs/show_bug.cgi?id=301110

Eike Stepper schrieb:
> Thomas Kowatsch schrieb:
>> Hmm Nope (see also the CDODeltaNotification javadoc below, only when
>> Collection#clear() is done). When it is just one element removed it
>> ends up in the REMOVE case where it uses getOldValue().
>> But REMOVE_MANY also has a potential problem, as getOldValue() should
>> return null and the listener in EMFListPropertyListener does:
>>
>> case Notification.REMOVE_MANY: {
>> Collection< ? > oldValues = (Collection< ? >)msg.getOldValue();
>> ListDiffEntry[] listDiffEntries = new ListDiffEntry[oldValues.size()];
>>
>> This will cause a NPE.
> We should fix that by returning at least an empty list. Please file a
> bugzilla.
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
Re: [CDO databinding] [message #510710 is a reply to message #510690] Thu, 28 January 2010 11:53 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Tom Schindl schrieb:
> [...]
>
>
>> The reason was/is that the old value is usually rarely used and very
>> expensive to determine and transfer by CDO in advance (i.e. with the
>> original CommitNotificationRequest). After the original notification it
>> would be impossible to lazily request it from the server if audfiting is
>> not enabled in the repository. We *could* discuss an enhancement in the
>> change subscription options so that there is a third option beside
>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>> (needed per object?, etc...) and quite some effort. to implement. Before
>> we even consider this discussion I'd like to understand what exactly the
>> old values are used for by data binding.
>>
>
> Eclipse-Databinding or in this case JFace-Databinding listens to changes
> in an ObservableList of Objects and adds/
Added objects are delivered by CDO.

> removes them from a JFace-Viewer.
>
Only the index of the removed objects is needed for that, and AFAIK
delivered by CDO.

Please notice that we're talking about *remote* detach here. A remote
client has removed an object (or many) and committed that change. The
particular objects are definitely and irreversibly "gone". They can not
be meaningfully resurrected. The only option for any other client in the
network is to release any hold of pointers to their stale copies.

> The only other option would be for the JFace-Databinding to refresh the
> complete viewers contents which is would decrease performance incredible.
>
> How would you implement an Table/List-UI which updates itself on changes
> of a List?
>
I suspect that the "UI part" still has a complete old list where the
detached object must just be removed (removal index should be
sufficient). Right?

> We could ask the JFace-Viewer-Databinding maintainers to add a special
> case in their code which leads to a complete refresh if the Diff is
> empty or holds an null-value but I guess CDOs behaviour breaks the
> API-contract of Eclipse-Databinding.
>
> Probably we should discuss with upstream if they have an API contract
> for a modification whose content couldn't be identified.
>
> What I don't completely understand is that the object removed in this
> case must be deleted from the local store/list as well (at least in the
> use case we see here it must have been on the client).
>
CDO automatically removes objects that were detached remotely from the
view cache so that they can no longer be retrieved from it. But if the
application or a higher-level framework like databinding is still
holding pointers (strong Java references) to any of these objects
they're still accessible through this "path". IIRC the application must
not use most of the normal getters or setters because an
IllegalStateException is thrown from them. To check that before calling
these methods you could investigate the cdoState() of these objects.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO databinding] [message #510720 is a reply to message #510710] Thu, 28 January 2010 08:02 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Am 28.01.10 12:53, schrieb Eike Stepper:
> Tom Schindl schrieb:
>> [...]
>>
>>
>>> The reason was/is that the old value is usually rarely used and very
>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>> original CommitNotificationRequest). After the original notification it
>>> would be impossible to lazily request it from the server if audfiting is
>>> not enabled in the repository. We *could* discuss an enhancement in the
>>> change subscription options so that there is a third option beside
>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>> we even consider this discussion I'd like to understand what exactly the
>>> old values are used for by data binding.
>>>
>>
>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>> in an ObservableList of Objects and adds/
> Added objects are delivered by CDO.
>
>> removes them from a JFace-Viewer.
>>
> Only the index of the removed objects is needed for that, and AFAIK
> delivered by CDO.
>
> Please notice that we're talking about *remote* detach here. A remote
> client has removed an object (or many) and committed that change. The
> particular objects are definitely and irreversibly "gone". They can not
> be meaningfully resurrected. The only option for any other client in the
> network is to release any hold of pointers to their stale copies.
>

No because the viewer can be reorder the entries based upon Sorters,
Filters, ... .

>> The only other option would be for the JFace-Databinding to refresh the
>> complete viewers contents which is would decrease performance incredible.
>>
>> How would you implement an Table/List-UI which updates itself on changes
>> of a List?
>>
> I suspect that the "UI part" still has a complete old list where the
> detached object must just be removed (removal index should be
> sufficient). Right?
>

No because if filters are applied to the viewer they are not part of it
any more and an index is not enough because when a ViewerSorter is
applied the list index != table-row-index (hence the viewer doesn't has
TableViewer#remove(int) but only TableViewer#remove(Object)).

>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>> case in their code which leads to a complete refresh if the Diff is
>> empty or holds an null-value but I guess CDOs behaviour breaks the
>> API-contract of Eclipse-Databinding.
>>
>> Probably we should discuss with upstream if they have an API contract
>> for a modification whose content couldn't be identified.
>>
>> What I don't completely understand is that the object removed in this
>> case must be deleted from the local store/list as well (at least in the
>> use case we see here it must have been on the client).
>>
> CDO automatically removes objects that were detached remotely from the
> view cache so that they can no longer be retrieved from it. But if the
> application or a higher-level framework like databinding is still
> holding pointers (strong Java references) to any of these objects

Well in this case it *could* be that the viewer holds a strong
references (if the element is not filtered out). DB itself is not
holding any pointers but it simply acts as an observe or the underlying
data structure.

Tom
Re: [CDO databinding] [message #510731 is a reply to message #510720] Thu, 28 January 2010 08:34 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Hi Tom,

It would probably mean non-standard processing from a databinding point
of view, but wouldn't it basically be easy to scan the affected lists
and just remove all CDOObjects with a state INVALID?

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper



Tom Schindl schrieb:
> Am 28.01.10 12:53, schrieb Eike Stepper:
>
>> Tom Schindl schrieb:
>>
>>> [...]
>>>
>>>
>>>
>>>> The reason was/is that the old value is usually rarely used and very
>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>> original CommitNotificationRequest). After the original notification it
>>>> would be impossible to lazily request it from the server if audfiting is
>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>> change subscription options so that there is a third option beside
>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>> we even consider this discussion I'd like to understand what exactly the
>>>> old values are used for by data binding.
>>>>
>>>>
>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>> in an ObservableList of Objects and adds/
>>>
>> Added objects are delivered by CDO.
>>
>>
>>> removes them from a JFace-Viewer.
>>>
>>>
>> Only the index of the removed objects is needed for that, and AFAIK
>> delivered by CDO.
>>
>> Please notice that we're talking about *remote* detach here. A remote
>> client has removed an object (or many) and committed that change. The
>> particular objects are definitely and irreversibly "gone". They can not
>> be meaningfully resurrected. The only option for any other client in the
>> network is to release any hold of pointers to their stale copies.
>>
>>
>
> No because the viewer can be reorder the entries based upon Sorters,
> Filters, ... .
>
>
>>> The only other option would be for the JFace-Databinding to refresh the
>>> complete viewers contents which is would decrease performance incredible.
>>>
>>> How would you implement an Table/List-UI which updates itself on changes
>>> of a List?
>>>
>>>
>> I suspect that the "UI part" still has a complete old list where the
>> detached object must just be removed (removal index should be
>> sufficient). Right?
>>
>>
>
> No because if filters are applied to the viewer they are not part of it
> any more and an index is not enough because when a ViewerSorter is
> applied the list index != table-row-index (hence the viewer doesn't has
> TableViewer#remove(int) but only TableViewer#remove(Object)).
>
>
>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>> case in their code which leads to a complete refresh if the Diff is
>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>> API-contract of Eclipse-Databinding.
>>>
>>> Probably we should discuss with upstream if they have an API contract
>>> for a modification whose content couldn't be identified.
>>>
>>> What I don't completely understand is that the object removed in this
>>> case must be deleted from the local store/list as well (at least in the
>>> use case we see here it must have been on the client).
>>>
>>>
>> CDO automatically removes objects that were detached remotely from the
>> view cache so that they can no longer be retrieved from it. But if the
>> application or a higher-level framework like databinding is still
>> holding pointers (strong Java references) to any of these objects
>>
>
> Well in this case it *could* be that the viewer holds a strong
> references (if the element is not filtered out). DB itself is not
> holding any pointers but it simply acts as an observe or the underlying
> data structure.
>
> Tom
>


Re: [CDO databinding] [message #510753 is a reply to message #510731] Thu, 28 January 2010 09:46 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Well the one that is in charge of this is list is out-of-scope for
EMF-Databinding because the only thing it knows is that someone is
observeing it and it informs this observe through a change-event (which
holds the missleading diff)

The only one who could do this scan in the case is JFace-Databinding
which naturally has no idea about CDO, EMF, ... (in general about the
domain technology) because from its point of view it only attaches
listeners to an IObservableList.

The only possible solution I can think of is that EMF-Databinding (4CDO)
has a mode where it internally holds a copy of the original observed
list to look up the correct objects and create the diff appropriately in
case of remote change notifications.

Tom

Am 28.01.10 14:28, schrieb Eike Stepper:
> Hi Tom,
>
> It would probably mean non-standard processing from a databinding point
> of view, but wouldn't it basically be easy to scan the affected lists
> and just remove all CDOObjects with a state INVALID?
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>
> Tom Schindl schrieb:
>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>
>>> Tom Schindl schrieb:
>>>
>>>> [...]
>>>>
>>>>
>>>>
>>>>> The reason was/is that the old value is usually rarely used and very
>>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>>> original CommitNotificationRequest). After the original notification it
>>>>> would be impossible to lazily request it from the server if audfiting is
>>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>>> change subscription options so that there is a third option beside
>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>>> we even consider this discussion I'd like to understand what exactly the
>>>>> old values are used for by data binding.
>>>>>
>>>>>
>>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>>> in an ObservableList of Objects and adds/
>>>>
>>> Added objects are delivered by CDO.
>>>
>>>
>>>> removes them from a JFace-Viewer.
>>>>
>>>>
>>> Only the index of the removed objects is needed for that, and AFAIK
>>> delivered by CDO.
>>>
>>> Please notice that we're talking about *remote* detach here. A remote
>>> client has removed an object (or many) and committed that change. The
>>> particular objects are definitely and irreversibly "gone". They can not
>>> be meaningfully resurrected. The only option for any other client in the
>>> network is to release any hold of pointers to their stale copies.
>>>
>>>
>>
>> No because the viewer can be reorder the entries based upon Sorters,
>> Filters, ... .
>>
>>
>>>> The only other option would be for the JFace-Databinding to refresh the
>>>> complete viewers contents which is would decrease performance incredible.
>>>>
>>>> How would you implement an Table/List-UI which updates itself on changes
>>>> of a List?
>>>>
>>>>
>>> I suspect that the "UI part" still has a complete old list where the
>>> detached object must just be removed (removal index should be
>>> sufficient). Right?
>>>
>>>
>>
>> No because if filters are applied to the viewer they are not part of it
>> any more and an index is not enough because when a ViewerSorter is
>> applied the list index != table-row-index (hence the viewer doesn't has
>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>
>>
>>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>>> case in their code which leads to a complete refresh if the Diff is
>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>> API-contract of Eclipse-Databinding.
>>>>
>>>> Probably we should discuss with upstream if they have an API contract
>>>> for a modification whose content couldn't be identified.
>>>>
>>>> What I don't completely understand is that the object removed in this
>>>> case must be deleted from the local store/list as well (at least in the
>>>> use case we see here it must have been on the client).
>>>>
>>>>
>>> CDO automatically removes objects that were detached remotely from the
>>> view cache so that they can no longer be retrieved from it. But if the
>>> application or a higher-level framework like databinding is still
>>> holding pointers (strong Java references) to any of these objects
>>>
>>
>> Well in this case it *could* be that the viewer holds a strong
>> references (if the element is not filtered out). DB itself is not
>> holding any pointers but it simply acts as an observe or the underlying
>> data structure.
>>
>> Tom
>>
Re: [CDO databinding] [message #510754 is a reply to message #510753] Thu, 28 January 2010 09:46 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Hi Tom,

I start to understand the "influences" although I don't have a solution
yet. Another thing I just realized is, that we (I at least) so far
talked about *detached* objects, i.e. elements of many-valued
*containment* features. I suspect the same problem occurs with removals
from cross references.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper



Tom Schindl schrieb:
> Well the one that is in charge of this is list is out-of-scope for
> EMF-Databinding because the only thing it knows is that someone is
> observeing it and it informs this observe through a change-event (which
> holds the missleading diff)
>
> The only one who could do this scan in the case is JFace-Databinding
> which naturally has no idea about CDO, EMF, ... (in general about the
> domain technology) because from its point of view it only attaches
> listeners to an IObservableList.
>
> The only possible solution I can think of is that EMF-Databinding (4CDO)
> has a mode where it internally holds a copy of the original observed
> list to look up the correct objects and create the diff appropriately in
> case of remote change notifications.
>
> Tom
>
> Am 28.01.10 14:28, schrieb Eike Stepper:
>
>> Hi Tom,
>>
>> It would probably mean non-standard processing from a databinding point
>> of view, but wouldn't it basically be easy to scan the affected lists
>> and just remove all CDOObjects with a state INVALID?
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>> Tom Schindl schrieb:
>>
>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>
>>>
>>>> Tom Schindl schrieb:
>>>>
>>>>
>>>>> [...]
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> The reason was/is that the old value is usually rarely used and very
>>>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>>>> original CommitNotificationRequest). After the original notification it
>>>>>> would be impossible to lazily request it from the server if audfiting is
>>>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>>>> change subscription options so that there is a third option beside
>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>>>> we even consider this discussion I'd like to understand what exactly the
>>>>>> old values are used for by data binding.
>>>>>>
>>>>>>
>>>>>>
>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>>>> in an ObservableList of Objects and adds/
>>>>>
>>>>>
>>>> Added objects are delivered by CDO.
>>>>
>>>>
>>>>
>>>>> removes them from a JFace-Viewer.
>>>>>
>>>>>
>>>>>
>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>> delivered by CDO.
>>>>
>>>> Please notice that we're talking about *remote* detach here. A remote
>>>> client has removed an object (or many) and committed that change. The
>>>> particular objects are definitely and irreversibly "gone". They can not
>>>> be meaningfully resurrected. The only option for any other client in the
>>>> network is to release any hold of pointers to their stale copies.
>>>>
>>>>
>>>>
>>> No because the viewer can be reorder the entries based upon Sorters,
>>> Filters, ... .
>>>
>>>
>>>
>>>>> The only other option would be for the JFace-Databinding to refresh the
>>>>> complete viewers contents which is would decrease performance incredible.
>>>>>
>>>>> How would you implement an Table/List-UI which updates itself on changes
>>>>> of a List?
>>>>>
>>>>>
>>>>>
>>>> I suspect that the "UI part" still has a complete old list where the
>>>> detached object must just be removed (removal index should be
>>>> sufficient). Right?
>>>>
>>>>
>>>>
>>> No because if filters are applied to the viewer they are not part of it
>>> any more and an index is not enough because when a ViewerSorter is
>>> applied the list index != table-row-index (hence the viewer doesn't has
>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>
>>>
>>>
>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>> API-contract of Eclipse-Databinding.
>>>>>
>>>>> Probably we should discuss with upstream if they have an API contract
>>>>> for a modification whose content couldn't be identified.
>>>>>
>>>>> What I don't completely understand is that the object removed in this
>>>>> case must be deleted from the local store/list as well (at least in the
>>>>> use case we see here it must have been on the client).
>>>>>
>>>>>
>>>>>
>>>> CDO automatically removes objects that were detached remotely from the
>>>> view cache so that they can no longer be retrieved from it. But if the
>>>> application or a higher-level framework like databinding is still
>>>> holding pointers (strong Java references) to any of these objects
>>>>
>>>>
>>> Well in this case it *could* be that the viewer holds a strong
>>> references (if the element is not filtered out). DB itself is not
>>> holding any pointers but it simply acts as an observe or the underlying
>>> data structure.
>>>
>>> Tom
>>>
>>>
>
>


Re: [CDO databinding] [message #510800 is a reply to message #510754] Thu, 28 January 2010 11:52 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33218
Registered: July 2009
Senior Member
Eike,

Yes, I imagine it will happen for any multi-valued feature, including
EAttributes. It seems likely that in all these cases, the UI itself
(the view) is still holding onto such old value, e.g., as data in a
TreeItem, while the control has no record of it.

Eike Stepper wrote:
> Hi Tom,
>
> I start to understand the "influences" although I don't have a solution
> yet. Another thing I just realized is, that we (I at least) so far
> talked about *detached* objects, i.e. elements of many-valued
> *containment* features. I suspect the same problem occurs with removals
> from cross references.
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>
> Tom Schindl schrieb:
>
>> Well the one that is in charge of this is list is out-of-scope for
>> EMF-Databinding because the only thing it knows is that someone is
>> observeing it and it informs this observe through a change-event (which
>> holds the missleading diff)
>>
>> The only one who could do this scan in the case is JFace-Databinding
>> which naturally has no idea about CDO, EMF, ... (in general about the
>> domain technology) because from its point of view it only attaches
>> listeners to an IObservableList.
>>
>> The only possible solution I can think of is that EMF-Databinding (4CDO)
>> has a mode where it internally holds a copy of the original observed
>> list to look up the correct objects and create the diff appropriately in
>> case of remote change notifications.
>>
>> Tom
>>
>> Am 28.01.10 14:28, schrieb Eike Stepper:
>>
>>
>>> Hi Tom,
>>>
>>> It would probably mean non-standard processing from a databinding point
>>> of view, but wouldn't it basically be easy to scan the affected lists
>>> and just remove all CDOObjects with a state INVALID?
>>>
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>
>>> Tom Schindl schrieb:
>>>
>>>
>>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>>
>>>>
>>>>
>>>>> Tom Schindl schrieb:
>>>>>
>>>>>
>>>>>
>>>>>> [...]
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> The reason was/is that the old value is usually rarely used and very
>>>>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>>>>> original CommitNotificationRequest). After the original notification it
>>>>>>> would be impossible to lazily request it from the server if audfiting is
>>>>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>>>>> change subscription options so that there is a third option beside
>>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>>>>> we even consider this discussion I'd like to understand what exactly the
>>>>>>> old values are used for by data binding.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>>>>> in an ObservableList of Objects and adds/
>>>>>>
>>>>>>
>>>>>>
>>>>> Added objects are delivered by CDO.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> removes them from a JFace-Viewer.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>>> delivered by CDO.
>>>>>
>>>>> Please notice that we're talking about *remote* detach here. A remote
>>>>> client has removed an object (or many) and committed that change. The
>>>>> particular objects are definitely and irreversibly "gone". They can not
>>>>> be meaningfully resurrected. The only option for any other client in the
>>>>> network is to release any hold of pointers to their stale copies.
>>>>>
>>>>>
>>>>>
>>>>>
>>>> No because the viewer can be reorder the entries based upon Sorters,
>>>> Filters, ... .
>>>>
>>>>
>>>>
>>>>
>>>>>> The only other option would be for the JFace-Databinding to refresh the
>>>>>> complete viewers contents which is would decrease performance incredible.
>>>>>>
>>>>>> How would you implement an Table/List-UI which updates itself on changes
>>>>>> of a List?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> I suspect that the "UI part" still has a complete old list where the
>>>>> detached object must just be removed (removal index should be
>>>>> sufficient). Right?
>>>>>
>>>>>
>>>>>
>>>>>
>>>> No because if filters are applied to the viewer they are not part of it
>>>> any more and an index is not enough because when a ViewerSorter is
>>>> applied the list index != table-row-index (hence the viewer doesn't has
>>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>>
>>>>
>>>>
>>>>
>>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>>> API-contract of Eclipse-Databinding.
>>>>>>
>>>>>> Probably we should discuss with upstream if they have an API contract
>>>>>> for a modification whose content couldn't be identified.
>>>>>>
>>>>>> What I don't completely understand is that the object removed in this
>>>>>> case must be deleted from the local store/list as well (at least in the
>>>>>> use case we see here it must have been on the client).
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> CDO automatically removes objects that were detached remotely from the
>>>>> view cache so that they can no longer be retrieved from it. But if the
>>>>> application or a higher-level framework like databinding is still
>>>>> holding pointers (strong Java references) to any of these objects
>>>>>
>>>>>
>>>>>
>>>> Well in this case it *could* be that the viewer holds a strong
>>>> references (if the element is not filtered out). DB itself is not
>>>> holding any pointers but it simply acts as an observe or the underlying
>>>> data structure.
>>>>
>>>> Tom
>>>>
>>>>
>>>>
>>
>>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [CDO databinding] [message #510813 is a reply to message #510800] Thu, 28 January 2010 17:01 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Ed Merks schrieb:
> Eike,
>
> Yes, I imagine it will happen for any multi-valued feature, including
> EAttributes. It seems likely that in all these cases, the UI itself
> (the view) is still holding onto such old value, e.g., as data in a
> TreeItem, while the control has no record of it.
Yes, that's what I meant. Either it holds onto these objects, or
explicit action is not necessary anyway.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>
> Eike Stepper wrote:
>> Hi Tom,
>>
>> I start to understand the "influences" although I don't have a solution
>> yet. Another thing I just realized is, that we (I at least) so far
>> talked about *detached* objects, i.e. elements of many-valued
>> *containment* features. I suspect the same problem occurs with removals
>> from cross references.
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>> Tom Schindl schrieb:
>>
>>> Well the one that is in charge of this is list is out-of-scope for
>>> EMF-Databinding because the only thing it knows is that someone is
>>> observeing it and it informs this observe through a change-event (which
>>> holds the missleading diff)
>>>
>>> The only one who could do this scan in the case is JFace-Databinding
>>> which naturally has no idea about CDO, EMF, ... (in general about the
>>> domain technology) because from its point of view it only attaches
>>> listeners to an IObservableList.
>>>
>>> The only possible solution I can think of is that EMF-Databinding
>>> (4CDO)
>>> has a mode where it internally holds a copy of the original observed
>>> list to look up the correct objects and create the diff
>>> appropriately in
>>> case of remote change notifications.
>>>
>>> Tom
>>>
>>> Am 28.01.10 14:28, schrieb Eike Stepper:
>>>
>>>> Hi Tom,
>>>>
>>>> It would probably mean non-standard processing from a databinding
>>>> point
>>>> of view, but wouldn't it basically be easy to scan the affected lists
>>>> and just remove all CDOObjects with a state INVALID?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>
>>>> Tom Schindl schrieb:
>>>>
>>>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>>>
>>>>>> Tom Schindl schrieb:
>>>>>>
>>>>>>> [...]
>>>>>>>
>>>>>>>
>>>>>>>> The reason was/is that the old value is usually rarely used and
>>>>>>>> very
>>>>>>>> expensive to determine and transfer by CDO in advance (i.e.
>>>>>>>> with the
>>>>>>>> original CommitNotificationRequest). After the original
>>>>>>>> notification it
>>>>>>>> would be impossible to lazily request it from the server if
>>>>>>>> audfiting is
>>>>>>>> not enabled in the repository. We *could* discuss an
>>>>>>>> enhancement in the
>>>>>>>> change subscription options so that there is a third option beside
>>>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>>>> (needed per object?, etc...) and quite some effort. to
>>>>>>>> implement. Before
>>>>>>>> we even consider this discussion I'd like to understand what
>>>>>>>> exactly the
>>>>>>>> old values are used for by data binding.
>>>>>>>>
>>>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to
>>>>>>> changes
>>>>>>> in an ObservableList of Objects and adds/
>>>>>>>
>>>>>> Added objects are delivered by CDO.
>>>>>>
>>>>>>
>>>>>>> removes them from a JFace-Viewer.
>>>>>>>
>>>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>>>> delivered by CDO.
>>>>>>
>>>>>> Please notice that we're talking about *remote* detach here. A
>>>>>> remote
>>>>>> client has removed an object (or many) and committed that change.
>>>>>> The
>>>>>> particular objects are definitely and irreversibly "gone". They
>>>>>> can not
>>>>>> be meaningfully resurrected. The only option for any other client
>>>>>> in the
>>>>>> network is to release any hold of pointers to their stale copies.
>>>>>>
>>>>>>
>>>>> No because the viewer can be reorder the entries based upon Sorters,
>>>>> Filters, ... .
>>>>>
>>>>>
>>>>>>> The only other option would be for the JFace-Databinding to
>>>>>>> refresh the
>>>>>>> complete viewers contents which is would decrease performance
>>>>>>> incredible.
>>>>>>>
>>>>>>> How would you implement an Table/List-UI which updates itself on
>>>>>>> changes
>>>>>>> of a List?
>>>>>>>
>>>>>> I suspect that the "UI part" still has a complete old list where the
>>>>>> detached object must just be removed (removal index should be
>>>>>> sufficient). Right?
>>>>>>
>>>>>>
>>>>> No because if filters are applied to the viewer they are not part
>>>>> of it
>>>>> any more and an index is not enough because when a ViewerSorter is
>>>>> applied the list index != table-row-index (hence the viewer
>>>>> doesn't has
>>>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>>>
>>>>>
>>>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a
>>>>>>> special
>>>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>>>> API-contract of Eclipse-Databinding.
>>>>>>>
>>>>>>> Probably we should discuss with upstream if they have an API
>>>>>>> contract
>>>>>>> for a modification whose content couldn't be identified.
>>>>>>>
>>>>>>> What I don't completely understand is that the object removed in
>>>>>>> this
>>>>>>> case must be deleted from the local store/list as well (at least
>>>>>>> in the
>>>>>>> use case we see here it must have been on the client).
>>>>>>>
>>>>>> CDO automatically removes objects that were detached remotely
>>>>>> from the
>>>>>> view cache so that they can no longer be retrieved from it. But
>>>>>> if the
>>>>>> application or a higher-level framework like databinding is still
>>>>>> holding pointers (strong Java references) to any of these objects
>>>>>>
>>>>> Well in this case it *could* be that the viewer holds a strong
>>>>> references (if the element is not filtered out). DB itself is not
>>>>> holding any pointers but it simply acts as an observe or the
>>>>> underlying
>>>>> data structure.
>>>>>
>>>>> Tom
>>>>>
>>>


Re: [CDO databinding] [message #510874 is a reply to message #510385] Thu, 28 January 2010 22:30 Go to previous messageGo to next message
Boris Bokowski is currently offline Boris BokowskiFriend
Messages: 272
Registered: July 2009
Senior Member
The following change in TableViewerUpdater could help, but only if the
TableViewer has no filter or sorter (if it has, the position information
cannot be used):
public void remove(Object element, int position) {

if (element != null) {

viewer.remove(element);

} else if (viewer.getComparator() == null &&
viewer.getFilters.length==0) {

viewer.remove(viewer.getElementAt(position));

} else {

throw new IllegalStateException("some useful message here");

}

}



Boris


"Thomas Kowatsch" <Thomas.Kowatsch@ruag.com> wrote in message
news:hjpaqo$e12$1@build.eclipse.org...
> Hi,
>
> I'm using EMF, CDO and databinding. I have a master detail scenario with a
> viewer and a detail part. I just was testing what happens when I have
> opened the application twice to see how the notification and update runs.
>
> Now I ran into the problem, that when I delete an entry in Appl1, it
> crashes in Appl2 when the viewer is refreshed from the
> ObservableListContentProvider. Here the stack trace:
>
>
> org.eclipse.core.runtime.AssertionFailedException: null argument:
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
> at
> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
> at
> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
> at
> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
> at
> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
> at
> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
> at
> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
> at
> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
> at org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
> at
> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
> at
> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
> at
> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
> ...
>
> So it seems that a "null" object is delivered to the viewer. I tried to
> track it down further and ended up in
> EMFListPropertyListener#notifyChanged(Notification). In the switch at case
> "Notification.REMOVE", a list diff is created with
> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(), false,
> msg.getOldValue())). Now I guess the problem is that msg.getOldValue()
> returns null!
>
> I checked that also in Appl1 (in the same CDOView that the element is
> deleted) and saw that msg.getOldValue() returns the deleted object.
>
> Is this actually a bug? If not then IMHO CDO and databinding is not usable
> as is.
>
> Cheers.
> --Thomas
Re: [CDO databinding] [message #510950 is a reply to message #510874] Fri, 29 January 2010 04:52 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Hi Boris,

Thanks for the info ;-)

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper



Boris Bokowski schrieb:
> The following change in TableViewerUpdater could help, but only if the
> TableViewer has no filter or sorter (if it has, the position information
> cannot be used):
> public void remove(Object element, int position) {
>
> if (element != null) {
>
> viewer.remove(element);
>
> } else if (viewer.getComparator() == null &&
> viewer.getFilters.length==0) {
>
> viewer.remove(viewer.getElementAt(position));
>
> } else {
>
> throw new IllegalStateException("some useful message here");
>
> }
>
> }
>
>
>
> Boris
>
>
> "Thomas Kowatsch" <Thomas.Kowatsch@ruag.com> wrote in message
> news:hjpaqo$e12$1@build.eclipse.org...
>
>> Hi,
>>
>> I'm using EMF, CDO and databinding. I have a master detail scenario with a
>> viewer and a detail part. I just was testing what happens when I have
>> opened the application twice to see how the notification and update runs.
>>
>> Now I ran into the problem, that when I delete an entry in Appl1, it
>> crashes in Appl2 when the viewer is refreshed from the
>> ObservableListContentProvider. Here the stack trace:
>>
>>
>> org.eclipse.core.runtime.AssertionFailedException: null argument:
>> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
>> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
>> at
>> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
>> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
>> at
>> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
>> at
>> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
>> at
>> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
>> at
>> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
>> at
>> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>> at
>> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
>> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
>> at org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
>> at
>> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
>> at
>> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
>> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
>> at
>> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
>> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
>> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
>> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
>> ...
>>
>> So it seems that a "null" object is delivered to the viewer. I tried to
>> track it down further and ended up in
>> EMFListPropertyListener#notifyChanged(Notification). In the switch at case
>> "Notification.REMOVE", a list diff is created with
>> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(), false,
>> msg.getOldValue())). Now I guess the problem is that msg.getOldValue()
>> returns null!
>>
>> I checked that also in Appl1 (in the same CDOView that the element is
>> deleted) and saw that msg.getOldValue() returns the deleted object.
>>
>> Is this actually a bug? If not then IMHO CDO and databinding is not usable
>> as is.
>>
>> Cheers.
>> --Thomas
>>
>
>
>


Re: [CDO databinding] [message #511595 is a reply to message #510754] Tue, 02 February 2010 08:30 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi Eike,

I rethought the issue and if I get this right the problem is when the
instance is *NOT* the local cache else you would have been able to look
it up from there?

Would it be possible for CDO to send a PRE-Remove Notification so that
clients who need a reference to the object can "prefetch" it so that it
gets part of the cache and your change notification can look it up from
there and provide the instance?

I'm going to bug Boris and Matt in the meantime to get their statement
on the change-notification in case the removed instance can't be provided.

Tom

Am 28.01.10 15:39, schrieb Eike Stepper:
> Hi Tom,
>
> I start to understand the "influences" although I don't have a solution
> yet. Another thing I just realized is, that we (I at least) so far
> talked about *detached* objects, i.e. elements of many-valued
> *containment* features. I suspect the same problem occurs with removals
> from cross references.
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>
> Tom Schindl schrieb:
>> Well the one that is in charge of this is list is out-of-scope for
>> EMF-Databinding because the only thing it knows is that someone is
>> observeing it and it informs this observe through a change-event (which
>> holds the missleading diff)
>>
>> The only one who could do this scan in the case is JFace-Databinding
>> which naturally has no idea about CDO, EMF, ... (in general about the
>> domain technology) because from its point of view it only attaches
>> listeners to an IObservableList.
>>
>> The only possible solution I can think of is that EMF-Databinding (4CDO)
>> has a mode where it internally holds a copy of the original observed
>> list to look up the correct objects and create the diff appropriately in
>> case of remote change notifications.
>>
>> Tom
>>
>> Am 28.01.10 14:28, schrieb Eike Stepper:
>>
>>> Hi Tom,
>>>
>>> It would probably mean non-standard processing from a databinding point
>>> of view, but wouldn't it basically be easy to scan the affected lists
>>> and just remove all CDOObjects with a state INVALID?
>>>
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>
>>> Tom Schindl schrieb:
>>>
>>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>>
>>>>
>>>>> Tom Schindl schrieb:
>>>>>
>>>>>
>>>>>> [...]
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> The reason was/is that the old value is usually rarely used and very
>>>>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>>>>> original CommitNotificationRequest). After the original notification it
>>>>>>> would be impossible to lazily request it from the server if audfiting is
>>>>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>>>>> change subscription options so that there is a third option beside
>>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>>>>> we even consider this discussion I'd like to understand what exactly the
>>>>>>> old values are used for by data binding.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>>>>> in an ObservableList of Objects and adds/
>>>>>>
>>>>>>
>>>>> Added objects are delivered by CDO.
>>>>>
>>>>>
>>>>>
>>>>>> removes them from a JFace-Viewer.
>>>>>>
>>>>>>
>>>>>>
>>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>>> delivered by CDO.
>>>>>
>>>>> Please notice that we're talking about *remote* detach here. A remote
>>>>> client has removed an object (or many) and committed that change. The
>>>>> particular objects are definitely and irreversibly "gone". They can not
>>>>> be meaningfully resurrected. The only option for any other client in the
>>>>> network is to release any hold of pointers to their stale copies.
>>>>>
>>>>>
>>>>>
>>>> No because the viewer can be reorder the entries based upon Sorters,
>>>> Filters, ... .
>>>>
>>>>
>>>>
>>>>>> The only other option would be for the JFace-Databinding to refresh the
>>>>>> complete viewers contents which is would decrease performance incredible.
>>>>>>
>>>>>> How would you implement an Table/List-UI which updates itself on changes
>>>>>> of a List?
>>>>>>
>>>>>>
>>>>>>
>>>>> I suspect that the "UI part" still has a complete old list where the
>>>>> detached object must just be removed (removal index should be
>>>>> sufficient). Right?
>>>>>
>>>>>
>>>>>
>>>> No because if filters are applied to the viewer they are not part of it
>>>> any more and an index is not enough because when a ViewerSorter is
>>>> applied the list index != table-row-index (hence the viewer doesn't has
>>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>>
>>>>
>>>>
>>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>>> API-contract of Eclipse-Databinding.
>>>>>>
>>>>>> Probably we should discuss with upstream if they have an API contract
>>>>>> for a modification whose content couldn't be identified.
>>>>>>
>>>>>> What I don't completely understand is that the object removed in this
>>>>>> case must be deleted from the local store/list as well (at least in the
>>>>>> use case we see here it must have been on the client).
>>>>>>
>>>>>>
>>>>>>
>>>>> CDO automatically removes objects that were detached remotely from the
>>>>> view cache so that they can no longer be retrieved from it. But if the
>>>>> application or a higher-level framework like databinding is still
>>>>> holding pointers (strong Java references) to any of these objects
>>>>>
>>>>>
>>>> Well in this case it *could* be that the viewer holds a strong
>>>> references (if the element is not filtered out). DB itself is not
>>>> holding any pointers but it simply acts as an observe or the underlying
>>>> data structure.
>>>>
>>>> Tom
>>>>
>>>>
>>
>>
Re: [CDO databinding] [message #511602 is a reply to message #510874] Tue, 02 February 2010 08:47 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

What would you think about doing a full-Refresh instead of throwing the
IllegalStateException?

Naturally the full refresh should not happen only once but that would at
least fix the issue for DB-Clients who can't identify the removed element.

Another probably also interesting question is whether the current
strategy in the viewer of modifying the content is always the best one
(certainly for a small set of entries it is good but if the changeset
gets larger I guess a full refresh outperforms it because the viewer
interally queues all updates and does them in 1 operation (without
disposing and recreating TableItems) instead of n (TableItem.dispose()
and TableItem-Creation) like the TableViewerUpdater.

So any easy fix to this problem would be to allow users to set the
TableViewerUpdater in a refresh-mode instead add/remove - ideally the
user can reconfigure the behaviour even after creation (e.g. in a
master-detail change I'd set the viewer in a refresh-mode whereas
normally I'd react on add/removes).

Tom

Am 28.01.10 23:30, schrieb Boris Bokowski:
> The following change in TableViewerUpdater could help, but only if the
> TableViewer has no filter or sorter (if it has, the position information
> cannot be used):
> public void remove(Object element, int position) {
>
> if (element != null) {
>
> viewer.remove(element);
>
> } else if (viewer.getComparator() == null &&
> viewer.getFilters.length==0) {
>
> viewer.remove(viewer.getElementAt(position));
>
> } else {
>
> throw new IllegalStateException("some useful message here");
>
> }
>
> }
>
>
>
> Boris
>
>
> "Thomas Kowatsch" <Thomas.Kowatsch@ruag.com> wrote in message
> news:hjpaqo$e12$1@build.eclipse.org...
>> Hi,
>>
>> I'm using EMF, CDO and databinding. I have a master detail scenario with a
>> viewer and a detail part. I just was testing what happens when I have
>> opened the application twice to see how the notification and update runs.
>>
>> Now I ran into the problem, that when I delete an entry in Appl1, it
>> crashes in Appl2 when the viewer is refreshed from the
>> ObservableListContentProvider. Here the stack trace:
>>
>>
>> org.eclipse.core.runtime.AssertionFailedException: null argument:
>> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
>> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
>> at
>> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
>> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
>> at
>> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
>> at
>> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
>> at
>> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
>> at
>> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
>> at
>> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>> at
>> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
>> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
>> at org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
>> at
>> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
>> at
>> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
>> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
>> at
>> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
>> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
>> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
>> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
>> ...
>>
>> So it seems that a "null" object is delivered to the viewer. I tried to
>> track it down further and ended up in
>> EMFListPropertyListener#notifyChanged(Notification). In the switch at case
>> "Notification.REMOVE", a list diff is created with
>> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(), false,
>> msg.getOldValue())). Now I guess the problem is that msg.getOldValue()
>> returns null!
>>
>> I checked that also in Appl1 (in the same CDOView that the element is
>> deleted) and saw that msg.getOldValue() returns the deleted object.
>>
>> Is this actually a bug? If not then IMHO CDO and databinding is not usable
>> as is.
>>
>> Cheers.
>> --Thomas
>
>
Re: [CDO databinding] [message #511610 is a reply to message #511595] Tue, 02 February 2010 04:28 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------010607010609030101060000
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

Tom Schindl schrieb:
> Hi Eike,
>
> I rethought the issue and if I get this right the problem is when the
> instance is *NOT* the local cache else you would have been able to look
> it up from there?
>
I verified that the instance will not be in the cache:

| *private static class *DetachRemoteTransition *implements *ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
*static *DetachRemoteTransition INSTANCE = *new *DetachRemoteTransition();

*public **void *execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
{
InternalCDOView view = object.cdoView();
_view.deregisterObject(object);_

_object.cdoInternalSetState(CDOState.INVALID);_
object.cdoInternalPostDetach(*true*);
}
}|


Note that, no matter through what pointer path an INVALID instance is
accessed, the instance will throw IllegalStateException from most of its
methods.

> Would it be possible for CDO to send a PRE-Remove Notification so that
> clients who need a reference to the object can "prefetch" it so that it
> gets part of the cache and your change notification can look it up from
> there and provide the instance?
>
That doesn't sound like a reasonable option. A notification like that
would really have to be an "agent-like" *request* rather than a one-way
notification. It would suspend the originating commit operation on the
server until all clients have signalled (responded) that they have done
what they wanted to do. Otherwise it would be very unlikely that they
get what they want to get (the old object data) because the commit
operation would already have overwritten this data. Synchronous requests
to all client from within the server commit operation are just not
acceptable.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


> I'm going to bug Boris and Matt in the meantime to get their statement
> on the change-notification in case the removed instance can't be provided.
>
> Tom
>
> Am 28.01.10 15:39, schrieb Eike Stepper:
>
>> Hi Tom,
>>
>> I start to understand the "influences" although I don't have a solution
>> yet. Another thing I just realized is, that we (I at least) so far
>> talked about *detached* objects, i.e. elements of many-valued
>> *containment* features. I suspect the same problem occurs with removals
>> from cross references.
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>> Tom Schindl schrieb:
>>
>>> Well the one that is in charge of this is list is out-of-scope for
>>> EMF-Databinding because the only thing it knows is that someone is
>>> observeing it and it informs this observe through a change-event (which
>>> holds the missleading diff)
>>>
>>> The only one who could do this scan in the case is JFace-Databinding
>>> which naturally has no idea about CDO, EMF, ... (in general about the
>>> domain technology) because from its point of view it only attaches
>>> listeners to an IObservableList.
>>>
>>> The only possible solution I can think of is that EMF-Databinding (4CDO)
>>> has a mode where it internally holds a copy of the original observed
>>> list to look up the correct objects and create the diff appropriately in
>>> case of remote change notifications.
>>>
>>> Tom
>>>
>>> Am 28.01.10 14:28, schrieb Eike Stepper:
>>>
>>>
>>>> Hi Tom,
>>>>
>>>> It would probably mean non-standard processing from a databinding point
>>>> of view, but wouldn't it basically be easy to scan the affected lists
>>>> and just remove all CDOObjects with a state INVALID?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>
>>>> Tom Schindl schrieb:
>>>>
>>>>
>>>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>>>
>>>>>
>>>>>
>>>>>> Tom Schindl schrieb:
>>>>>>
>>>>>>
>>>>>>
>>>>>>> [...]
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> The reason was/is that the old value is usually rarely used and very
>>>>>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>>>>>> original CommitNotificationRequest). After the original notification it
>>>>>>>> would be impossible to lazily request it from the server if audfiting is
>>>>>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>>>>>> change subscription options so that there is a third option beside
>>>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>>>>>> we even consider this discussion I'd like to understand what exactly the
>>>>>>>> old values are used for by data binding.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>>>>>> in an ObservableList of Objects and adds/
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> Added objects are delivered by CDO.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> removes them from a JFace-Viewer.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>>>> delivered by CDO.
>>>>>>
>>>>>> Please notice that we're talking about *remote* detach here. A remote
>>>>>> client has removed an object (or many) and committed that change. The
>>>>>> particular objects are definitely and irreversibly "gone". They can not
>>>>>> be meaningfully resurrected. The only option for any other client in the
>>>>>> network is to release any hold of pointers to their stale copies.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> No because the viewer can be reorder the entries based upon Sorters,
>>>>> Filters, ... .
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>> The only other option would be for the JFace-Databinding to refresh the
>>>>>>> complete viewers contents which is would decrease performance incredible.
>>>>>>>
>>>>>>> How would you implement an Table/List-UI which updates itself on changes
>>>>>>> of a List?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> I suspect that the "UI part" still has a complete old list where the
>>>>>> detached object must just be removed (removal index should be
>>>>>> sufficient). Right?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> No because if filters are applied to the viewer they are not part of it
>>>>> any more and an index is not enough because when a ViewerSorter is
>>>>> applied the list index != table-row-index (hence the viewer doesn't has
>>>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>>>> API-contract of Eclipse-Databinding.
>>>>>>>
>>>>>>> Probably we should discuss with upstream if they have an API contract
>>>>>>> for a modification whose content couldn't be identified.
>>>>>>>
>>>>>>> What I don't completely understand is that the object removed in this
>>>>>>> case must be deleted from the local store/list as well (at least in the
>>>>>>> use case we see here it must have been on the client).
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> CDO automatically removes objects that were detached remotely from the
>>>>>> view cache so that they can no longer be retrieved from it. But if the
>>>>>> application or a higher-level framework like databinding is still
>>>>>> holding pointers (strong Java references) to any of these objects
>>>>>>
>>>>>>
>>>>>>
>>>>> Well in this case it *could* be that the viewer holds a strong
>>>>> references (if the element is not filtered out). DB itself is not
>>>>> holding any pointers but it simply acts as an observe or the underlying
>>>>> data structure.
>>>>>
>>>>> Tom
>>>>>
>>>>>
>>>>>
>>>
>>>
>
>

--------------010607010609030101060000
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Tom Schindl schrieb:
<blockquote cite="mid:hk8nri$3ip$1@build.eclipse.org" type="cite">
<pre wrap="">Hi Eike,

I rethought the issue and if I get this right the problem is when the
instance is *NOT* the local cache else you would have been able to look
it up from there?
</pre>
</blockquote>
I verified that the instance will not be in the cache:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#ffffff">


Re: [CDO databinding] [message #515416 is a reply to message #510385] Thu, 18 February 2010 12:46 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Hi.

Is there anybody out there who is still working on a solution of this
problem?

Or at least thinking about a solution?

This problem is essential to our project and our project will fail, if
there is none, as we relied on the fact that databinding is working
together with CDO.

IMO it works excellent as long as you are working with one CDOView or
CDOTransaction. As soon as you have a remote CDVOView the whole thing is
behaving very bad when you e.g. remove an object.

One reason is that CDODeltaNotification is unable to deliver all needed
data for databinding, i.e. on remove, the oldValue is just missing.

Another reason is that when accessing an INVALID CDOObject, an exception
is thrown.

I tried to work araound those problems a bit, just to get it running.
But when I solved one problem just one or more other come up.

What I have done so far:

- first I tried to solve the issue that ViewerUpdater will fail when
remove is called with a null (that is now fixed) or an empty collection
element. I just wrote a custom ViewerUpdater that is passed to
ObservableListContentProvider. I just did a refresh() in any case the
needed information is missing. In my example here that would be if
remove(Object element, int position) is called with an empty list, I do
a refresh().

- that worked quite ok, but then I had the next problem. We are having a
master-detail situation and I followed the instructions from Tom's blog
about EMF databinding. This uses a WriteableValue for the master
observable. Everything worked quite ok, until the remote viewer (the
viewer in the application that gets the remote remove notification) has
currently selected the remotely removed element. In this case the
WritableValue will get a value change because the selection of the
viewer changes (the element was removed). Now a diff is created with the
old, INVALID CDOObject as oldValue. Whenever this oldValue is accessed
(or lets say an attribute of the oldValue) it will fail with the
exception. So I though I overwrite two methods of WritableValue to solve
this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
fireValueChange() I check if the oldValue in the passed diff is an
invalid object and if it is, I replace it with null and carry on with
super.fireValueChange(). in doGetValue() I check if the cached value is
an invalid object and return null in case. This solved the problems so
far for all clients using the WritableValue or have a
ValueChangedListener attached.

- that is all ok and handable when it is in your program code. But if
you use framework code you cannot overwrite this. The
....observeDetail(master) methods create DetailObservableValues that hold
the master value as currentOuterValue. If this object is an INVALID
CDOObject, then it fails when the master changes as in the
outerChangeListener a doGetValue() is done at the beginning which tries
to read an EAttribute from the INVALID object. I guess this happens
throughout all databinding master-detail objects. For example, the label
provider uses an attribute map to observe the attributes that are
displayed by the LabelProvider, these are in generell
DetailObservableValues which might access the INVALID object's attributes.

At this point I decided to write this post, as I'm quite stuck and don't
know how to proceed. I have no idea anymore how to solve that myself...

Any advices?

Cheers.
--Thomas
Re: [CDO databinding] [message #515417 is a reply to message #515416] Thu, 18 February 2010 12:46 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Hi Thomas,

Okay, there seem to be these two, different issues:

1) No old value for REMOVE and REMOVE_MANY
2) Objects in state INVALID after remote deletion

I must admit that, from a distance, I can not understand all the
concrete details about databinding. I could offer to play with a working
example if you provide that. I suggest that we talk via Skype about that.

I could imagine that I can solve 1) somehow in CDO, e.g. optionally
broadcast the old values and feed the adapters with them.

But I don't see so much how 2) can be solved generically. In a
distributed concurrent environment soe things *are* just different.
Maybe with more knowledge about databinding I get a new idea...

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper




Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
> Hi.
>
> Is there anybody out there who is still working on a solution of this
> problem?
>
> Or at least thinking about a solution?
>
> This problem is essential to our project and our project will fail, if
> there is none, as we relied on the fact that databinding is working
> together with CDO.
>
> IMO it works excellent as long as you are working with one CDOView or
> CDOTransaction. As soon as you have a remote CDVOView the whole thing
> is behaving very bad when you e.g. remove an object.
>
> One reason is that CDODeltaNotification is unable to deliver all
> needed data for databinding, i.e. on remove, the oldValue is just
> missing.
>
> Another reason is that when accessing an INVALID CDOObject, an
> exception is thrown.
>
> I tried to work araound those problems a bit, just to get it running.
> But when I solved one problem just one or more other come up.
>
> What I have done so far:
>
> - first I tried to solve the issue that ViewerUpdater will fail when
> remove is called with a null (that is now fixed) or an empty
> collection element. I just wrote a custom ViewerUpdater that is passed
> to ObservableListContentProvider. I just did a refresh() in any case
> the needed information is missing. In my example here that would be if
> remove(Object element, int position) is called with an empty list, I
> do a refresh().
>
> - that worked quite ok, but then I had the next problem. We are having
> a master-detail situation and I followed the instructions from Tom's
> blog about EMF databinding. This uses a WriteableValue for the master
> observable. Everything worked quite ok, until the remote viewer (the
> viewer in the application that gets the remote remove notification)
> has currently selected the remotely removed element. In this case the
> WritableValue will get a value change because the selection of the
> viewer changes (the element was removed). Now a diff is created with
> the old, INVALID CDOObject as oldValue. Whenever this oldValue is
> accessed (or lets say an attribute of the oldValue) it will fail with
> the exception. So I though I overwrite two methods of WritableValue to
> solve this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
> fireValueChange() I check if the oldValue in the passed diff is an
> invalid object and if it is, I replace it with null and carry on with
> super.fireValueChange(). in doGetValue() I check if the cached value
> is an invalid object and return null in case. This solved the problems
> so far for all clients using the WritableValue or have a
> ValueChangedListener attached.
>
> - that is all ok and handable when it is in your program code. But if
> you use framework code you cannot overwrite this. The
> ....observeDetail(master) methods create DetailObservableValues that
> hold the master value as currentOuterValue. If this object is an
> INVALID CDOObject, then it fails when the master changes as in the
> outerChangeListener a doGetValue() is done at the beginning which
> tries to read an EAttribute from the INVALID object. I guess this
> happens throughout all databinding master-detail objects. For example,
> the label provider uses an attribute map to observe the attributes
> that are displayed by the LabelProvider, these are in generell
> DetailObservableValues which might access the INVALID object's
> attributes.
>
> At this point I decided to write this post, as I'm quite stuck and
> don't know how to proceed. I have no idea anymore how to solve that
> myself...
>
> Any advices?
>
> Cheers.
> --Thomas


Re: [CDO databinding] [message #515425 is a reply to message #515417] Thu, 18 February 2010 13:16 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Hi Eike.
Many thanks for the quick answer.
Comments below.
Cheers.
--Thomas

Eike Stepper schrieb:
> Hi Thomas,
>
> Okay, there seem to be these two, different issues:
>
> 1) No old value for REMOVE and REMOVE_MANY
> 2) Objects in state INVALID after remote deletion
>
> I must admit that, from a distance, I can not understand all the
> concrete details about databinding. I could offer to play with a working
> example if you provide that. I suggest that we talk via Skype about that.
>
> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
> broadcast the old values and feed the adapters with them.
Ok. But this problem is not so bad, as it can be solved with a custom
ViewerUpdater as I described below. But maybe thats also an option which
might be needed by others in CDO...
>
> But I don't see so much how 2) can be solved generically. In a
> distributed concurrent environment soe things *are* just different.
> Maybe with more knowledge about databinding I get a new idea...
Ideas, that was one of the reasons for my latest post. At the moment I
can only think about a special CDO adapted databinding package.... But
this will be hard and great effort, I guess...
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>
>
> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>> Hi.
>>
>> Is there anybody out there who is still working on a solution of this
>> problem?
>>
>> Or at least thinking about a solution?
>>
>> This problem is essential to our project and our project will fail, if
>> there is none, as we relied on the fact that databinding is working
>> together with CDO.
>>
>> IMO it works excellent as long as you are working with one CDOView or
>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>> is behaving very bad when you e.g. remove an object.
>>
>> One reason is that CDODeltaNotification is unable to deliver all
>> needed data for databinding, i.e. on remove, the oldValue is just
>> missing.
>>
>> Another reason is that when accessing an INVALID CDOObject, an
>> exception is thrown.
>>
>> I tried to work araound those problems a bit, just to get it running.
>> But when I solved one problem just one or more other come up.
>>
>> What I have done so far:
>>
>> - first I tried to solve the issue that ViewerUpdater will fail when
>> remove is called with a null (that is now fixed) or an empty
>> collection element. I just wrote a custom ViewerUpdater that is passed
>> to ObservableListContentProvider. I just did a refresh() in any case
>> the needed information is missing. In my example here that would be if
>> remove(Object element, int position) is called with an empty list, I
>> do a refresh().
>>
>> - that worked quite ok, but then I had the next problem. We are having
>> a master-detail situation and I followed the instructions from Tom's
>> blog about EMF databinding. This uses a WriteableValue for the master
>> observable. Everything worked quite ok, until the remote viewer (the
>> viewer in the application that gets the remote remove notification)
>> has currently selected the remotely removed element. In this case the
>> WritableValue will get a value change because the selection of the
>> viewer changes (the element was removed). Now a diff is created with
>> the old, INVALID CDOObject as oldValue. Whenever this oldValue is
>> accessed (or lets say an attribute of the oldValue) it will fail with
>> the exception. So I though I overwrite two methods of WritableValue to
>> solve this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
>> fireValueChange() I check if the oldValue in the passed diff is an
>> invalid object and if it is, I replace it with null and carry on with
>> super.fireValueChange(). in doGetValue() I check if the cached value
>> is an invalid object and return null in case. This solved the problems
>> so far for all clients using the WritableValue or have a
>> ValueChangedListener attached.
>>
>> - that is all ok and handable when it is in your program code. But if
>> you use framework code you cannot overwrite this. The
>> ....observeDetail(master) methods create DetailObservableValues that
>> hold the master value as currentOuterValue. If this object is an
>> INVALID CDOObject, then it fails when the master changes as in the
>> outerChangeListener a doGetValue() is done at the beginning which
>> tries to read an EAttribute from the INVALID object. I guess this
>> happens throughout all databinding master-detail objects. For example,
>> the label provider uses an attribute map to observe the attributes
>> that are displayed by the LabelProvider, these are in generell
>> DetailObservableValues which might access the INVALID object's
>> attributes.
>>
>> At this point I decided to write this post, as I'm quite stuck and
>> don't know how to proceed. I have no idea anymore how to solve that
>> myself...
>>
>> Any advices?
>>
>> Cheers.
>> --Thomas
Re: [CDO databinding] [message #515426 is a reply to message #515425] Thu, 18 February 2010 13:16 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

Ideally we get some JUnit-Test-Cases so that Eike and I can get together
and find a solution.

Probably we even need upstream support. Just an idea would it be
possible to configure CDO so that it returns a NULL instead of throwing
an exception when someone wants to access an attribute of an INVALID-Object?

Ideally Eclipse-Databinding would provide API to configure error
handling for such cases. The main problem is that M6 is API-Freeze and
the chance to get new API in at this stage is quite hard (probably
impossible).

Tom

Am 18.02.10 18:59, schrieb Thomas Kowatsch:
> Hi Eike.
> Many thanks for the quick answer.
> Comments below.
> Cheers.
> --Thomas
>
> Eike Stepper schrieb:
>> Hi Thomas,
>>
>> Okay, there seem to be these two, different issues:
>>
>> 1) No old value for REMOVE and REMOVE_MANY
>> 2) Objects in state INVALID after remote deletion
>>
>> I must admit that, from a distance, I can not understand all the
>> concrete details about databinding. I could offer to play with a
>> working example if you provide that. I suggest that we talk via Skype
>> about that.
>>
>> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
>> broadcast the old values and feed the adapters with them.
> Ok. But this problem is not so bad, as it can be solved with a custom
> ViewerUpdater as I described below. But maybe thats also an option which
> might be needed by others in CDO...
>>
>> But I don't see so much how 2) can be solved generically. In a
>> distributed concurrent environment soe things *are* just different.
>> Maybe with more knowledge about databinding I get a new idea...
> Ideas, that was one of the reasons for my latest post. At the moment I
> can only think about a special CDO adapted databinding package.... But
> this will be hard and great effort, I guess...
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>>
>> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>>> Hi.
>>>
>>> Is there anybody out there who is still working on a solution of this
>>> problem?
>>>
>>> Or at least thinking about a solution?
>>>
>>> This problem is essential to our project and our project will fail,
>>> if there is none, as we relied on the fact that databinding is
>>> working together with CDO.
>>>
>>> IMO it works excellent as long as you are working with one CDOView or
>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>>> is behaving very bad when you e.g. remove an object.
>>>
>>> One reason is that CDODeltaNotification is unable to deliver all
>>> needed data for databinding, i.e. on remove, the oldValue is just
>>> missing.
>>>
>>> Another reason is that when accessing an INVALID CDOObject, an
>>> exception is thrown.
>>>
>>> I tried to work araound those problems a bit, just to get it running.
>>> But when I solved one problem just one or more other come up.
>>>
>>> What I have done so far:
>>>
>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>> remove is called with a null (that is now fixed) or an empty
>>> collection element. I just wrote a custom ViewerUpdater that is
>>> passed to ObservableListContentProvider. I just did a refresh() in
>>> any case the needed information is missing. In my example here that
>>> would be if remove(Object element, int position) is called with an
>>> empty list, I do a refresh().
>>>
>>> - that worked quite ok, but then I had the next problem. We are
>>> having a master-detail situation and I followed the instructions from
>>> Tom's blog about EMF databinding. This uses a WriteableValue for the
>>> master observable. Everything worked quite ok, until the remote
>>> viewer (the viewer in the application that gets the remote remove
>>> notification) has currently selected the remotely removed element. In
>>> this case the WritableValue will get a value change because the
>>> selection of the viewer changes (the element was removed). Now a diff
>>> is created with the old, INVALID CDOObject as oldValue. Whenever this
>>> oldValue is accessed (or lets say an attribute of the oldValue) it
>>> will fail with the exception. So I though I overwrite two methods of
>>> WritableValue to solve this issue, i.e. fireValueChange(ValueDiff)
>>> and goGetValue(). In fireValueChange() I check if the oldValue in the
>>> passed diff is an invalid object and if it is, I replace it with null
>>> and carry on with super.fireValueChange(). in doGetValue() I check if
>>> the cached value is an invalid object and return null in case. This
>>> solved the problems so far for all clients using the WritableValue or
>>> have a ValueChangedListener attached.
>>>
>>> - that is all ok and handable when it is in your program code. But if
>>> you use framework code you cannot overwrite this. The
>>> ....observeDetail(master) methods create DetailObservableValues that
>>> hold the master value as currentOuterValue. If this object is an
>>> INVALID CDOObject, then it fails when the master changes as in the
>>> outerChangeListener a doGetValue() is done at the beginning which
>>> tries to read an EAttribute from the INVALID object. I guess this
>>> happens throughout all databinding master-detail objects. For
>>> example, the label provider uses an attribute map to observe the
>>> attributes that are displayed by the LabelProvider, these are in
>>> generell DetailObservableValues which might access the INVALID
>>> object's attributes.
>>>
>>> At this point I decided to write this post, as I'm quite stuck and
>>> don't know how to proceed. I have no idea anymore how to solve that
>>> myself...
>>>
>>> Any advices?
>>>
>>> Cheers.
>>> --Thomas
Re: [CDO databinding] [message #515508 is a reply to message #515426] Fri, 19 February 2010 06:04 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Am 18.02.2010 19:09, schrieb Tom Schindl:
> Hi,
>
> Ideally we get some JUnit-Test-Cases so that Eike and I can get together
> and find a solution.
>
Yes, that should be the next step.

> Probably we even need upstream support. Just an idea would it be
> possible to configure CDO so that it returns a NULL instead of throwing
> an exception when someone wants to access an attribute of an INVALID-Object?
>
That has been discussed earlier but I'm not a fan of this "hack", as it
leaves a client with in a state that just is invalid with respect to the
repository state and then there's no way of even recognizing this.

> Ideally Eclipse-Databinding would provide API to configure error
> handling for such cases. The main problem is that M6 is API-Freeze and
> the chance to get new API in at this stage is quite hard (probably
> impossible).
>
We can only try. Try quickly ;-)

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


> Tom
>
> Am 18.02.10 18:59, schrieb Thomas Kowatsch:
>
>> Hi Eike.
>> Many thanks for the quick answer.
>> Comments below.
>> Cheers.
>> --Thomas
>>
>> Eike Stepper schrieb:
>>
>>> Hi Thomas,
>>>
>>> Okay, there seem to be these two, different issues:
>>>
>>> 1) No old value for REMOVE and REMOVE_MANY
>>> 2) Objects in state INVALID after remote deletion
>>>
>>> I must admit that, from a distance, I can not understand all the
>>> concrete details about databinding. I could offer to play with a
>>> working example if you provide that. I suggest that we talk via Skype
>>> about that.
>>>
>>> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
>>> broadcast the old values and feed the adapters with them.
>>>
>> Ok. But this problem is not so bad, as it can be solved with a custom
>> ViewerUpdater as I described below. But maybe thats also an option which
>> might be needed by others in CDO...
>>
>>> But I don't see so much how 2) can be solved generically. In a
>>> distributed concurrent environment soe things *are* just different.
>>> Maybe with more knowledge about databinding I get a new idea...
>>>
>> Ideas, that was one of the reasons for my latest post. At the moment I
>> can only think about a special CDO adapted databinding package.... But
>> this will be hard and great effort, I guess...
>>
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>
>>>
>>> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>>>
>>>> Hi.
>>>>
>>>> Is there anybody out there who is still working on a solution of this
>>>> problem?
>>>>
>>>> Or at least thinking about a solution?
>>>>
>>>> This problem is essential to our project and our project will fail,
>>>> if there is none, as we relied on the fact that databinding is
>>>> working together with CDO.
>>>>
>>>> IMO it works excellent as long as you are working with one CDOView or
>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>>>> is behaving very bad when you e.g. remove an object.
>>>>
>>>> One reason is that CDODeltaNotification is unable to deliver all
>>>> needed data for databinding, i.e. on remove, the oldValue is just
>>>> missing.
>>>>
>>>> Another reason is that when accessing an INVALID CDOObject, an
>>>> exception is thrown.
>>>>
>>>> I tried to work araound those problems a bit, just to get it running.
>>>> But when I solved one problem just one or more other come up.
>>>>
>>>> What I have done so far:
>>>>
>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>> remove is called with a null (that is now fixed) or an empty
>>>> collection element. I just wrote a custom ViewerUpdater that is
>>>> passed to ObservableListContentProvider. I just did a refresh() in
>>>> any case the needed information is missing. In my example here that
>>>> would be if remove(Object element, int position) is called with an
>>>> empty list, I do a refresh().
>>>>
>>>> - that worked quite ok, but then I had the next problem. We are
>>>> having a master-detail situation and I followed the instructions from
>>>> Tom's blog about EMF databinding. This uses a WriteableValue for the
>>>> master observable. Everything worked quite ok, until the remote
>>>> viewer (the viewer in the application that gets the remote remove
>>>> notification) has currently selected the remotely removed element. In
>>>> this case the WritableValue will get a value change because the
>>>> selection of the viewer changes (the element was removed). Now a diff
>>>> is created with the old, INVALID CDOObject as oldValue. Whenever this
>>>> oldValue is accessed (or lets say an attribute of the oldValue) it
>>>> will fail with the exception. So I though I overwrite two methods of
>>>> WritableValue to solve this issue, i.e. fireValueChange(ValueDiff)
>>>> and goGetValue(). In fireValueChange() I check if the oldValue in the
>>>> passed diff is an invalid object and if it is, I replace it with null
>>>> and carry on with super.fireValueChange(). in doGetValue() I check if
>>>> the cached value is an invalid object and return null in case. This
>>>> solved the problems so far for all clients using the WritableValue or
>>>> have a ValueChangedListener attached.
>>>>
>>>> - that is all ok and handable when it is in your program code. But if
>>>> you use framework code you cannot overwrite this. The
>>>> ....observeDetail(master) methods create DetailObservableValues that
>>>> hold the master value as currentOuterValue. If this object is an
>>>> INVALID CDOObject, then it fails when the master changes as in the
>>>> outerChangeListener a doGetValue() is done at the beginning which
>>>> tries to read an EAttribute from the INVALID object. I guess this
>>>> happens throughout all databinding master-detail objects. For
>>>> example, the label provider uses an attribute map to observe the
>>>> attributes that are displayed by the LabelProvider, these are in
>>>> generell DetailObservableValues which might access the INVALID
>>>> object's attributes.
>>>>
>>>> At this point I decided to write this post, as I'm quite stuck and
>>>> don't know how to proceed. I have no idea anymore how to solve that
>>>> myself...
>>>>
>>>> Any advices?
>>>>
>>>> Cheers.
>>>> --Thomas
>>>>
>


Re: [CDO databinding] [message #515523 is a reply to message #515426] Fri, 19 February 2010 04:26 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Hi Tom.
Comments below...
Cheers.
--Thomas

Tom Schindl schrieb:
> Hi,
>
> Ideally we get some JUnit-Test-Cases so that Eike and I can get together
> and find a solution.
I will do that on Monday with a colleague. It is quite a bit of work
though, as the situation is a bit complicated (need two transactions,
master-detail scenario, no UI, ...). Is there any test for an EMF/CDO
Databinding master-detail scenario which could be taken as base?
>
> Probably we even need upstream support. Just an idea would it be
> possible to configure CDO so that it returns a NULL instead of throwing
> an exception when someone wants to access an attribute of an INVALID-Object?
>
> Ideally Eclipse-Databinding would provide API to configure error
> handling for such cases. The main problem is that M6 is API-Freeze and
> the chance to get new API in at this stage is quite hard (probably
> impossible).
>
> Tom
>
> Am 18.02.10 18:59, schrieb Thomas Kowatsch:
>> Hi Eike.
>> Many thanks for the quick answer.
>> Comments below.
>> Cheers.
>> --Thomas
>>
>> Eike Stepper schrieb:
>>> Hi Thomas,
>>>
>>> Okay, there seem to be these two, different issues:
>>>
>>> 1) No old value for REMOVE and REMOVE_MANY
>>> 2) Objects in state INVALID after remote deletion
>>>
>>> I must admit that, from a distance, I can not understand all the
>>> concrete details about databinding. I could offer to play with a
>>> working example if you provide that. I suggest that we talk via Skype
>>> about that.
>>>
>>> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
>>> broadcast the old values and feed the adapters with them.
>> Ok. But this problem is not so bad, as it can be solved with a custom
>> ViewerUpdater as I described below. But maybe thats also an option which
>> might be needed by others in CDO...
>>> But I don't see so much how 2) can be solved generically. In a
>>> distributed concurrent environment soe things *are* just different.
>>> Maybe with more knowledge about databinding I get a new idea...
>> Ideas, that was one of the reasons for my latest post. At the moment I
>> can only think about a special CDO adapted databinding package.... But
>> this will be hard and great effort, I guess...
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>
>>>
>>> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>>>> Hi.
>>>>
>>>> Is there anybody out there who is still working on a solution of this
>>>> problem?
>>>>
>>>> Or at least thinking about a solution?
>>>>
>>>> This problem is essential to our project and our project will fail,
>>>> if there is none, as we relied on the fact that databinding is
>>>> working together with CDO.
>>>>
>>>> IMO it works excellent as long as you are working with one CDOView or
>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>>>> is behaving very bad when you e.g. remove an object.
>>>>
>>>> One reason is that CDODeltaNotification is unable to deliver all
>>>> needed data for databinding, i.e. on remove, the oldValue is just
>>>> missing.
>>>>
>>>> Another reason is that when accessing an INVALID CDOObject, an
>>>> exception is thrown.
>>>>
>>>> I tried to work araound those problems a bit, just to get it running.
>>>> But when I solved one problem just one or more other come up.
>>>>
>>>> What I have done so far:
>>>>
>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>> remove is called with a null (that is now fixed) or an empty
>>>> collection element. I just wrote a custom ViewerUpdater that is
>>>> passed to ObservableListContentProvider. I just did a refresh() in
>>>> any case the needed information is missing. In my example here that
>>>> would be if remove(Object element, int position) is called with an
>>>> empty list, I do a refresh().
>>>>
>>>> - that worked quite ok, but then I had the next problem. We are
>>>> having a master-detail situation and I followed the instructions from
>>>> Tom's blog about EMF databinding. This uses a WriteableValue for the
>>>> master observable. Everything worked quite ok, until the remote
>>>> viewer (the viewer in the application that gets the remote remove
>>>> notification) has currently selected the remotely removed element. In
>>>> this case the WritableValue will get a value change because the
>>>> selection of the viewer changes (the element was removed). Now a diff
>>>> is created with the old, INVALID CDOObject as oldValue. Whenever this
>>>> oldValue is accessed (or lets say an attribute of the oldValue) it
>>>> will fail with the exception. So I though I overwrite two methods of
>>>> WritableValue to solve this issue, i.e. fireValueChange(ValueDiff)
>>>> and goGetValue(). In fireValueChange() I check if the oldValue in the
>>>> passed diff is an invalid object and if it is, I replace it with null
>>>> and carry on with super.fireValueChange(). in doGetValue() I check if
>>>> the cached value is an invalid object and return null in case. This
>>>> solved the problems so far for all clients using the WritableValue or
>>>> have a ValueChangedListener attached.
>>>>
>>>> - that is all ok and handable when it is in your program code. But if
>>>> you use framework code you cannot overwrite this. The
>>>> ....observeDetail(master) methods create DetailObservableValues that
>>>> hold the master value as currentOuterValue. If this object is an
>>>> INVALID CDOObject, then it fails when the master changes as in the
>>>> outerChangeListener a doGetValue() is done at the beginning which
>>>> tries to read an EAttribute from the INVALID object. I guess this
>>>> happens throughout all databinding master-detail objects. For
>>>> example, the label provider uses an attribute map to observe the
>>>> attributes that are displayed by the LabelProvider, these are in
>>>> generell DetailObservableValues which might access the INVALID
>>>> object's attributes.
>>>>
>>>> At this point I decided to write this post, as I'm quite stuck and
>>>> don't know how to proceed. I have no idea anymore how to solve that
>>>> myself...
>>>>
>>>> Any advices?
>>>>
>>>> Cheers.
>>>> --Thomas
>
Re: [CDO databinding] [message #515524 is a reply to message #515523] Fri, 19 February 2010 04:26 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Am 19.02.2010 10:03, schrieb Thomas Kowatsch:
> Hi Tom.
> Comments below...
> Cheers.
> --Thomas
>
> Tom Schindl schrieb:
>> Hi,
>>
>> Ideally we get some JUnit-Test-Cases so that Eike and I can get together
>> and find a solution.
> I will do that on Monday with a colleague. It is quite a bit of work
> though, as the situation is a bit complicated (need two transactions,
> master-detail scenario, no UI, ...). Is there any test for an EMF/CDO
> Databinding master-detail scenario which could be taken as base?
Not that I know of. Tom?

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>>
>> Probably we even need upstream support. Just an idea would it be
>> possible to configure CDO so that it returns a NULL instead of throwing
>> an exception when someone wants to access an attribute of an
>> INVALID-Object?
>>
>> Ideally Eclipse-Databinding would provide API to configure error
>> handling for such cases. The main problem is that M6 is API-Freeze and
>> the chance to get new API in at this stage is quite hard (probably
>> impossible).
>>
>> Tom
>>
>> Am 18.02.10 18:59, schrieb Thomas Kowatsch:
>>> Hi Eike.
>>> Many thanks for the quick answer.
>>> Comments below.
>>> Cheers.
>>> --Thomas
>>>
>>> Eike Stepper schrieb:
>>>> Hi Thomas,
>>>>
>>>> Okay, there seem to be these two, different issues:
>>>>
>>>> 1) No old value for REMOVE and REMOVE_MANY
>>>> 2) Objects in state INVALID after remote deletion
>>>>
>>>> I must admit that, from a distance, I can not understand all the
>>>> concrete details about databinding. I could offer to play with a
>>>> working example if you provide that. I suggest that we talk via Skype
>>>> about that.
>>>>
>>>> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
>>>> broadcast the old values and feed the adapters with them.
>>> Ok. But this problem is not so bad, as it can be solved with a custom
>>> ViewerUpdater as I described below. But maybe thats also an option
>>> which
>>> might be needed by others in CDO...
>>>> But I don't see so much how 2) can be solved generically. In a
>>>> distributed concurrent environment soe things *are* just different.
>>>> Maybe with more knowledge about databinding I get a new idea...
>>> Ideas, that was one of the reasons for my latest post. At the moment I
>>> can only think about a special CDO adapted databinding package.... But
>>> this will be hard and great effort, I guess...
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>
>>>>
>>>> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>>>>> Hi.
>>>>>
>>>>> Is there anybody out there who is still working on a solution of this
>>>>> problem?
>>>>>
>>>>> Or at least thinking about a solution?
>>>>>
>>>>> This problem is essential to our project and our project will fail,
>>>>> if there is none, as we relied on the fact that databinding is
>>>>> working together with CDO.
>>>>>
>>>>> IMO it works excellent as long as you are working with one CDOView or
>>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>>>>> is behaving very bad when you e.g. remove an object.
>>>>>
>>>>> One reason is that CDODeltaNotification is unable to deliver all
>>>>> needed data for databinding, i.e. on remove, the oldValue is just
>>>>> missing.
>>>>>
>>>>> Another reason is that when accessing an INVALID CDOObject, an
>>>>> exception is thrown.
>>>>>
>>>>> I tried to work araound those problems a bit, just to get it running.
>>>>> But when I solved one problem just one or more other come up.
>>>>>
>>>>> What I have done so far:
>>>>>
>>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>>> remove is called with a null (that is now fixed) or an empty
>>>>> collection element. I just wrote a custom ViewerUpdater that is
>>>>> passed to ObservableListContentProvider. I just did a refresh() in
>>>>> any case the needed information is missing. In my example here that
>>>>> would be if remove(Object element, int position) is called with an
>>>>> empty list, I do a refresh().
>>>>>
>>>>> - that worked quite ok, but then I had the next problem. We are
>>>>> having a master-detail situation and I followed the instructions from
>>>>> Tom's blog about EMF databinding. This uses a WriteableValue for the
>>>>> master observable. Everything worked quite ok, until the remote
>>>>> viewer (the viewer in the application that gets the remote remove
>>>>> notification) has currently selected the remotely removed element. In
>>>>> this case the WritableValue will get a value change because the
>>>>> selection of the viewer changes (the element was removed). Now a diff
>>>>> is created with the old, INVALID CDOObject as oldValue. Whenever this
>>>>> oldValue is accessed (or lets say an attribute of the oldValue) it
>>>>> will fail with the exception. So I though I overwrite two methods of
>>>>> WritableValue to solve this issue, i.e. fireValueChange(ValueDiff)
>>>>> and goGetValue(). In fireValueChange() I check if the oldValue in the
>>>>> passed diff is an invalid object and if it is, I replace it with null
>>>>> and carry on with super.fireValueChange(). in doGetValue() I check if
>>>>> the cached value is an invalid object and return null in case. This
>>>>> solved the problems so far for all clients using the WritableValue or
>>>>> have a ValueChangedListener attached.
>>>>>
>>>>> - that is all ok and handable when it is in your program code. But if
>>>>> you use framework code you cannot overwrite this. The
>>>>> ....observeDetail(master) methods create DetailObservableValues that
>>>>> hold the master value as currentOuterValue. If this object is an
>>>>> INVALID CDOObject, then it fails when the master changes as in the
>>>>> outerChangeListener a doGetValue() is done at the beginning which
>>>>> tries to read an EAttribute from the INVALID object. I guess this
>>>>> happens throughout all databinding master-detail objects. For
>>>>> example, the label provider uses an attribute map to observe the
>>>>> attributes that are displayed by the LabelProvider, these are in
>>>>> generell DetailObservableValues which might access the INVALID
>>>>> object's attributes.
>>>>>
>>>>> At this point I decided to write this post, as I'm quite stuck and
>>>>> don't know how to proceed. I have no idea anymore how to solve that
>>>>> myself...
>>>>>
>>>>> Any advices?
>>>>>
>>>>> Cheers.
>>>>> --Thomas
>>


Re: [CDO databinding] [message #515539 is a reply to message #515524] Fri, 19 February 2010 10:09 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
No.
Am 19.02.10 10:18, schrieb Eike Stepper:
> Am 19.02.2010 10:03, schrieb Thomas Kowatsch:
>> Hi Tom.
>> Comments below...
>> Cheers.
>> --Thomas
>>
>> Tom Schindl schrieb:
>>> Hi,
>>>
>>> Ideally we get some JUnit-Test-Cases so that Eike and I can get together
>>> and find a solution.
>> I will do that on Monday with a colleague. It is quite a bit of work
>> though, as the situation is a bit complicated (need two transactions,
>> master-detail scenario, no UI, ...). Is there any test for an EMF/CDO
>> Databinding master-detail scenario which could be taken as base?
> Not that I know of. Tom?
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>>>
>>> Probably we even need upstream support. Just an idea would it be
>>> possible to configure CDO so that it returns a NULL instead of throwing
>>> an exception when someone wants to access an attribute of an
>>> INVALID-Object?
>>>
>>> Ideally Eclipse-Databinding would provide API to configure error
>>> handling for such cases. The main problem is that M6 is API-Freeze and
>>> the chance to get new API in at this stage is quite hard (probably
>>> impossible).
>>>
>>> Tom
>>>
>>> Am 18.02.10 18:59, schrieb Thomas Kowatsch:
>>>> Hi Eike.
>>>> Many thanks for the quick answer.
>>>> Comments below.
>>>> Cheers.
>>>> --Thomas
>>>>
>>>> Eike Stepper schrieb:
>>>>> Hi Thomas,
>>>>>
>>>>> Okay, there seem to be these two, different issues:
>>>>>
>>>>> 1) No old value for REMOVE and REMOVE_MANY
>>>>> 2) Objects in state INVALID after remote deletion
>>>>>
>>>>> I must admit that, from a distance, I can not understand all the
>>>>> concrete details about databinding. I could offer to play with a
>>>>> working example if you provide that. I suggest that we talk via Skype
>>>>> about that.
>>>>>
>>>>> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
>>>>> broadcast the old values and feed the adapters with them.
>>>> Ok. But this problem is not so bad, as it can be solved with a custom
>>>> ViewerUpdater as I described below. But maybe thats also an option
>>>> which
>>>> might be needed by others in CDO...
>>>>> But I don't see so much how 2) can be solved generically. In a
>>>>> distributed concurrent environment soe things *are* just different.
>>>>> Maybe with more knowledge about databinding I get a new idea...
>>>> Ideas, that was one of the reasons for my latest post. At the moment I
>>>> can only think about a special CDO adapted databinding package.... But
>>>> this will be hard and great effort, I guess...
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>> ----
>>>>> http://thegordian.blogspot.com
>>>>> http://twitter.com/eikestepper
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>>>>>> Hi.
>>>>>>
>>>>>> Is there anybody out there who is still working on a solution of this
>>>>>> problem?
>>>>>>
>>>>>> Or at least thinking about a solution?
>>>>>>
>>>>>> This problem is essential to our project and our project will fail,
>>>>>> if there is none, as we relied on the fact that databinding is
>>>>>> working together with CDO.
>>>>>>
>>>>>> IMO it works excellent as long as you are working with one CDOView or
>>>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>>>>>> is behaving very bad when you e.g. remove an object.
>>>>>>
>>>>>> One reason is that CDODeltaNotification is unable to deliver all
>>>>>> needed data for databinding, i.e. on remove, the oldValue is just
>>>>>> missing.
>>>>>>
>>>>>> Another reason is that when accessing an INVALID CDOObject, an
>>>>>> exception is thrown.
>>>>>>
>>>>>> I tried to work araound those problems a bit, just to get it running.
>>>>>> But when I solved one problem just one or more other come up.
>>>>>>
>>>>>> What I have done so far:
>>>>>>
>>>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>>>> remove is called with a null (that is now fixed) or an empty
>>>>>> collection element. I just wrote a custom ViewerUpdater that is
>>>>>> passed to ObservableListContentProvider. I just did a refresh() in
>>>>>> any case the needed information is missing. In my example here that
>>>>>> would be if remove(Object element, int position) is called with an
>>>>>> empty list, I do a refresh().
>>>>>>
>>>>>> - that worked quite ok, but then I had the next problem. We are
>>>>>> having a master-detail situation and I followed the instructions from
>>>>>> Tom's blog about EMF databinding. This uses a WriteableValue for the
>>>>>> master observable. Everything worked quite ok, until the remote
>>>>>> viewer (the viewer in the application that gets the remote remove
>>>>>> notification) has currently selected the remotely removed element. In
>>>>>> this case the WritableValue will get a value change because the
>>>>>> selection of the viewer changes (the element was removed). Now a diff
>>>>>> is created with the old, INVALID CDOObject as oldValue. Whenever this
>>>>>> oldValue is accessed (or lets say an attribute of the oldValue) it
>>>>>> will fail with the exception. So I though I overwrite two methods of
>>>>>> WritableValue to solve this issue, i.e. fireValueChange(ValueDiff)
>>>>>> and goGetValue(). In fireValueChange() I check if the oldValue in the
>>>>>> passed diff is an invalid object and if it is, I replace it with null
>>>>>> and carry on with super.fireValueChange(). in doGetValue() I check if
>>>>>> the cached value is an invalid object and return null in case. This
>>>>>> solved the problems so far for all clients using the WritableValue or
>>>>>> have a ValueChangedListener attached.
>>>>>>
>>>>>> - that is all ok and handable when it is in your program code. But if
>>>>>> you use framework code you cannot overwrite this. The
>>>>>> ....observeDetail(master) methods create DetailObservableValues that
>>>>>> hold the master value as currentOuterValue. If this object is an
>>>>>> INVALID CDOObject, then it fails when the master changes as in the
>>>>>> outerChangeListener a doGetValue() is done at the beginning which
>>>>>> tries to read an EAttribute from the INVALID object. I guess this
>>>>>> happens throughout all databinding master-detail objects. For
>>>>>> example, the label provider uses an attribute map to observe the
>>>>>> attributes that are displayed by the LabelProvider, these are in
>>>>>> generell DetailObservableValues which might access the INVALID
>>>>>> object's attributes.
>>>>>>
>>>>>> At this point I decided to write this post, as I'm quite stuck and
>>>>>> don't know how to proceed. I have no idea anymore how to solve that
>>>>>> myself...
>>>>>>
>>>>>> Any advices?
>>>>>>
>>>>>> Cheers.
>>>>>> --Thomas
>>>
Re: [CDO databinding] [message #515560 is a reply to message #510385] Fri, 19 February 2010 10:56 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Good news!

I think I was able to provide proper old values for event kind REMOVE.
If the remotely detached object is locally available it can be accessed
via CDODeltaNotification.getOldValue() ;-)

The fix is available in HEAD or via p2:
https://build.eclipse.org/hudson/job/emf-cdo-integration/las tSuccessfulBuild/artifact/result/site.p2
(starting from build #141).

Does that help?

Please note that there might still be an issue with REMOVE_MANY. CDO
will emit a series of REMOVE notifications even if
list.remove(Collection) has been called remotely. That by itself should
not be a problem, but we're sending a REMOVE_Many notification with an
empty list as old value after list.clear() has been called. Can you
please test how that works with databinding?

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO databinding] [message #515562 is a reply to message #515560] Fri, 19 February 2010 11:19 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Am 19.02.2010 11:56, schrieb Eike Stepper:
> [...] CDO will emit a series of REMOVE notifications even if
> list.removeAll(Collection) has been called remotely.
That's not exactly true!

The CDONotificationBuilder will construct multiple REMOVE Notifications
but these will get merged by EMF. The result is one REMOVE_MANY
Notification with the correct oldValue list. Cool ;-)

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO databinding] [message #515564 is a reply to message #515560] Fri, 19 February 2010 11:21 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Hi Eike.
Sounds good. I will test it also on Monday when we updated CDO from HEAD.
Can you explain a bit more when it could be the case that "the remotely
detached object is locally available" is not fulfilled?
Cheers.
--Thomas

Eike Stepper schrieb:
> Good news!
>
> I think I was able to provide proper old values for event kind REMOVE.
> If the remotely detached object is locally available it can be accessed
> via CDODeltaNotification.getOldValue() ;-)
>
> The fix is available in HEAD or via p2:
> https://build.eclipse.org/hudson/job/emf-cdo-integration/las tSuccessfulBuild/artifact/result/site.p2
> (starting from build #141).
>
> Does that help?
>
> Please note that there might still be an issue with REMOVE_MANY. CDO
> will emit a series of REMOVE notifications even if
> list.remove(Collection) has been called remotely. That by itself should
> not be a problem, but we're sending a REMOVE_Many notification with an
> empty list as old value after list.clear() has been called. Can you
> please test how that works with databinding?
>
> Cheers
> /Eike
>
> ----
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
Re: [CDO databinding] [message #515565 is a reply to message #515564] Fri, 19 February 2010 11:27 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Eike could correct me but an object is wiped from the local cache if it
is not referenced any more in your client code and the garbage-collector
finished his job.

It's fullfilled by definition if you are using it in a Viewer because
the viewer holds a strong reference to the object, which is generally a
bad idea but helps you in this case :-)

Tom

Am 19.02.10 12:21, schrieb Thomas Kowatsch:
> Hi Eike.
> Sounds good. I will test it also on Monday when we updated CDO from HEAD.
> Can you explain a bit more when it could be the case that "the remotely
> detached object is locally available" is not fulfilled?
> Cheers.
> --Thomas
>
> Eike Stepper schrieb:
>> Good news!
>>
>> I think I was able to provide proper old values for event kind REMOVE.
>> If the remotely detached object is locally available it can be
>> accessed via CDODeltaNotification.getOldValue() ;-)
>>
>> The fix is available in HEAD or via p2:
>> https://build.eclipse.org/hudson/job/emf-cdo-integration/las tSuccessfulBuild/artifact/result/site.p2
>> (starting from build #141).
>>
>> Does that help?
>>
>> Please note that there might still be an issue with REMOVE_MANY. CDO
>> will emit a series of REMOVE notifications even if
>> list.remove(Collection) has been called remotely. That by itself
>> should not be a problem, but we're sending a REMOVE_Many notification
>> with an empty list as old value after list.clear() has been called.
>> Can you please test how that works with databinding?
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
Re: [CDO databinding] [message #515584 is a reply to message #515564] Fri, 19 February 2010 08:12 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Am 19.02.2010 12:21, schrieb Thomas Kowatsch:
> Hi Eike.
> Sounds good. I will test it also on Monday when we updated CDO from HEAD.
Great. I just fixed it for cross-referenced elements as well.

> Can you explain a bit more when it could be the case that "the
> remotely detached object is locally available" is not fulfilled?
It's fulfilled in most cases. But these are not of interest in this
context because adapters should keep the adapted objects in local memory.

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


> Cheers.
> --Thomas
>
> Eike Stepper schrieb:
>> Good news!
>>
>> I think I was able to provide proper old values for event kind
>> REMOVE. If the remotely detached object is locally available it can
>> be accessed via CDODeltaNotification.getOldValue() ;-)
>>
>> The fix is available in HEAD or via p2:
>> https://build.eclipse.org/hudson/job/emf-cdo-integration/las tSuccessfulBuild/artifact/result/site.p2
>> (starting from build #141).
>>
>> Does that help?
>>
>> Please note that there might still be an issue with REMOVE_MANY. CDO
>> will emit a series of REMOVE notifications even if
>> list.remove(Collection) has been called remotely. That by itself
>> should not be a problem, but we're sending a REMOVE_Many notification
>> with an empty list as old value after list.clear() has been called.
>> Can you please test how that works with databinding?
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>


Re: [CDO databinding] [message #515585 is a reply to message #515565] Fri, 19 February 2010 08:12 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
Am 19.02.2010 12:27, schrieb Tom Schindl:
> Eike could correct me but an object is wiped from the local cache if it
> is not referenced any more in your client code and the garbage-collector
> finished his job.
>
> It's fullfilled by definition if you are using it in a Viewer because
> the viewer holds a strong reference to the object, which is generally a
> bad idea but helps you in this case :-)
>
I couldn't have said it better ;-)

Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper


> Tom
>
> Am 19.02.10 12:21, schrieb Thomas Kowatsch:
>
>> Hi Eike.
>> Sounds good. I will test it also on Monday when we updated CDO from HEAD.
>> Can you explain a bit more when it could be the case that "the remotely
>> detached object is locally available" is not fulfilled?
>> Cheers.
>> --Thomas
>>
>> Eike Stepper schrieb:
>>
>>> Good news!
>>>
>>> I think I was able to provide proper old values for event kind REMOVE.
>>> If the remotely detached object is locally available it can be
>>> accessed via CDODeltaNotification.getOldValue() ;-)
>>>
>>> The fix is available in HEAD or via p2:
>>> https://build.eclipse.org/hudson/job/emf-cdo-integration/las tSuccessfulBuild/artifact/result/site.p2
>>> (starting from build #141).
>>>
>>> Does that help?
>>>
>>> Please note that there might still be an issue with REMOVE_MANY. CDO
>>> will emit a series of REMOVE notifications even if
>>> list.remove(Collection) has been called remotely. That by itself
>>> should not be a problem, but we're sending a REMOVE_Many notification
>>> with an empty list as old value after list.clear() has been called.
>>> Can you please test how that works with databinding?
>>>
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>
>


Re: [CDO databinding] [message #516194 is a reply to message #515416] Tue, 23 February 2010 02:22 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi Thomas,

Can you at least provide a stacktrace for the master detail problem so
that we can see the offending method calls?

Tom

Am 18.02.10 18:13, schrieb Thomas Kowatsch:
> Hi.
>
> Is there anybody out there who is still working on a solution of this
> problem?
>
> Or at least thinking about a solution?
>
> This problem is essential to our project and our project will fail, if
> there is none, as we relied on the fact that databinding is working
> together with CDO.
>
> IMO it works excellent as long as you are working with one CDOView or
> CDOTransaction. As soon as you have a remote CDVOView the whole thing is
> behaving very bad when you e.g. remove an object.
>
> One reason is that CDODeltaNotification is unable to deliver all needed
> data for databinding, i.e. on remove, the oldValue is just missing.
>
> Another reason is that when accessing an INVALID CDOObject, an exception
> is thrown.
>
> I tried to work araound those problems a bit, just to get it running.
> But when I solved one problem just one or more other come up.
>
> What I have done so far:
>
> - first I tried to solve the issue that ViewerUpdater will fail when
> remove is called with a null (that is now fixed) or an empty collection
> element. I just wrote a custom ViewerUpdater that is passed to
> ObservableListContentProvider. I just did a refresh() in any case the
> needed information is missing. In my example here that would be if
> remove(Object element, int position) is called with an empty list, I do
> a refresh().
>
> - that worked quite ok, but then I had the next problem. We are having a
> master-detail situation and I followed the instructions from Tom's blog
> about EMF databinding. This uses a WriteableValue for the master
> observable. Everything worked quite ok, until the remote viewer (the
> viewer in the application that gets the remote remove notification) has
> currently selected the remotely removed element. In this case the
> WritableValue will get a value change because the selection of the
> viewer changes (the element was removed). Now a diff is created with the
> old, INVALID CDOObject as oldValue. Whenever this oldValue is accessed
> (or lets say an attribute of the oldValue) it will fail with the
> exception. So I though I overwrite two methods of WritableValue to solve
> this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
> fireValueChange() I check if the oldValue in the passed diff is an
> invalid object and if it is, I replace it with null and carry on with
> super.fireValueChange(). in doGetValue() I check if the cached value is
> an invalid object and return null in case. This solved the problems so
> far for all clients using the WritableValue or have a
> ValueChangedListener attached.
>
> - that is all ok and handable when it is in your program code. But if
> you use framework code you cannot overwrite this. The
> ...observeDetail(master) methods create DetailObservableValues that hold
> the master value as currentOuterValue. If this object is an INVALID
> CDOObject, then it fails when the master changes as in the
> outerChangeListener a doGetValue() is done at the beginning which tries
> to read an EAttribute from the INVALID object. I guess this happens
> throughout all databinding master-detail objects. For example, the label
> provider uses an attribute map to observe the attributes that are
> displayed by the LabelProvider, these are in generell
> DetailObservableValues which might access the INVALID object's attributes.
>
> At this point I decided to write this post, as I'm quite stuck and don't
> know how to proceed. I have no idea anymore how to solve that myself...
>
> Any advices?
>
> Cheers.
> --Thomas
Re: [CDO databinding] [message #516206 is a reply to message #516194] Tue, 23 February 2010 03:34 Go to previous messageGo to next message
Erwin Betschart is currently offline Erwin BetschartFriend
Messages: 4
Registered: July 2009
Junior Member
This is a multi-part message in MIME format.
--------------000503080607090109090408
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Hi Tom

I wrote a CDO testcase together with Thomas. I've attached a patch for
the org.eclipse.emf.cdo.tests project.

The problem is that databinding stores cdo object which can become
invalid and throw runtime exceptions on access.

[ERROR] Object OID4 is not valid in branch 0 at *
org.eclipse.emf.cdo.util.InvalidObjectException: Object OID4 is not
valid in branch 0 at *
at
org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1029)
at
org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1)
at
org.eclipse.net4j.util.fsm.FiniteStateMachine.process(Finite StateMachine.java:162)
at
org.eclipse.emf.internal.cdo.CDOStateMachine.read(CDOStateMa chine.java:322)
at
org.eclipse.emf.internal.cdo.CDOStore.getRevisionForReading( CDOStore.java:604)
at org.eclipse.emf.internal.cdo.CDOStore.get(CDOStore.java:173)
at
org.eclipse.emf.internal.cdo.CDOObjectImpl.dynamicGet(CDOObj ectImpl.java:494)
at
org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1986)
at
org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1037)
at
org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1021)
at
org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1013)
at
org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1008)
at
org.eclipse.emf.databinding.internal.EMFValueProperty.doGetV alue(EMFValueProperty.java:63)
at
org.eclipse.core.databinding.property.value.SimpleValuePrope rty.getValue(SimpleValueProperty.java:55)
at
org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.notifyIfChanged(SimplePropertyObserva bleValue.java:115)
at
org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.doGetValue(SimplePropertyObservableVa lue.java:97)
at
org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.getValue(AbstractObservableValue.java:76)
at
org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$8.run(DetailObservableValue.java:142 )
at
org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
at
org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue.doGetValue(DetailObservableValue.jav a:140)
at
org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$3.run(DetailObservableValue.java:88)
at
org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
at
org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$2.handleValueChange(DetailObservable Value.java:86)
at
org.eclipse.core.databinding.observable.value.ValueChangeEve nt.dispatch(ValueChangeEvent.java:62)
at
org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
at
org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.fireValueChange(AbstractObservableValue.java:71)
at
org.eclipse.core.databinding.observable.value.WritableValue. doSetValue(WritableValue.java:92)
at
org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.setValue(AbstractObservableValue.java:55)
at
org.eclipse.emf.cdo.tests.CdoDatabindingMasterDetailTest$2.h andleListChange(CdoDatabindingMasterDetailTest.java:117)
at
org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
at
org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
at
org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
at
org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
at
org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
at
org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
at
org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
at
org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
at
org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:112)
at
org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
at
org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
at
org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
at org.eclipse.core.databinding.observable.Realm.exec(Realm.jav a:170)
at
org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$1.handleEvent(SimplePropertyObservableL ist.java:74)
at
org.eclipse.emf.databinding.internal.EMFPropertyListener$EMF ListPropertyListener.notifyChanged(EMFPropertyListener.java: 159)
at
org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify (BasicNotifierImpl.java:280)
at
org.eclipse.emf.common.notify.impl.NotificationImpl.dispatch (NotificationImpl.java:1033)
at
org.eclipse.emf.internal.cdo.view.CDOViewImpl.handleChangeSu bscription(CDOViewImpl.java:1469)
at
org.eclipse.emf.internal.cdo.view.CDOViewImpl.invalidate(CDO ViewImpl.java:1324)
at
org.eclipse.emf.internal.cdo.session.CDOSessionImpl$Invalida tionRunnable.run(CDOSessionImpl.java:1114)
at org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:26)
at org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:1)
at org.eclipse.net4j.util.concurrent.QueueWorker.work(QueueWork er.java:64)
at
org.eclipse.net4j.util.concurrent.Worker$WorkerThread.run(Wo rker.java:188)



Tom Schindl schrieb:
> Hi Thomas,
>
> Can you at least provide a stacktrace for the master detail problem so
> that we can see the offending method calls?
>
> Tom
>
> Am 18.02.10 18:13, schrieb Thomas Kowatsch:
>> Hi.
>>
>> Is there anybody out there who is still working on a solution of this
>> problem?
>>
>> Or at least thinking about a solution?
>>
>> This problem is essential to our project and our project will fail, if
>> there is none, as we relied on the fact that databinding is working
>> together with CDO.
>>
>> IMO it works excellent as long as you are working with one CDOView or
>> CDOTransaction. As soon as you have a remote CDVOView the whole thing is
>> behaving very bad when you e.g. remove an object.
>>
>> One reason is that CDODeltaNotification is unable to deliver all needed
>> data for databinding, i.e. on remove, the oldValue is just missing.
>>
>> Another reason is that when accessing an INVALID CDOObject, an exception
>> is thrown.
>>
>> I tried to work araound those problems a bit, just to get it running.
>> But when I solved one problem just one or more other come up.
>>
>> What I have done so far:
>>
>> - first I tried to solve the issue that ViewerUpdater will fail when
>> remove is called with a null (that is now fixed) or an empty collection
>> element. I just wrote a custom ViewerUpdater that is passed to
>> ObservableListContentProvider. I just did a refresh() in any case the
>> needed information is missing. In my example here that would be if
>> remove(Object element, int position) is called with an empty list, I do
>> a refresh().
>>
>> - that worked quite ok, but then I had the next problem. We are having a
>> master-detail situation and I followed the instructions from Tom's blog
>> about EMF databinding. This uses a WriteableValue for the master
>> observable. Everything worked quite ok, until the remote viewer (the
>> viewer in the application that gets the remote remove notification) has
>> currently selected the remotely removed element. In this case the
>> WritableValue will get a value change because the selection of the
>> viewer changes (the element was removed). Now a diff is created with the
>> old, INVALID CDOObject as oldValue. Whenever this oldValue is accessed
>> (or lets say an attribute of the oldValue) it will fail with the
>> exception. So I though I overwrite two methods of WritableValue to solve
>> this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
>> fireValueChange() I check if the oldValue in the passed diff is an
>> invalid object and if it is, I replace it with null and carry on with
>> super.fireValueChange(). in doGetValue() I check if the cached value is
>> an invalid object and return null in case. This solved the problems so
>> far for all clients using the WritableValue or have a
>> ValueChangedListener attached.
>>
>> - that is all ok and handable when it is in your program code. But if
>> you use framework code you cannot overwrite this. The
>> ...observeDetail(master) methods create DetailObservableValues that hold
>> the master value as currentOuterValue. If this object is an INVALID
>> CDOObject, then it fails when the master changes as in the
>> outerChangeListener a doGetValue() is done at the beginning which tries
>> to read an EAttribute from the INVALID object. I guess this happens
>> throughout all databinding master-detail objects. For example, the label
>> provider uses an attribute map to observe the attributes that are
>> displayed by the LabelProvider, these are in generell
>> DetailObservableValues which might access the INVALID object's attributes.
>>
>> At this point I decided to write this post, as I'm quite stuck and don't
>> know how to proceed. I have no idea anymore how to solve that myself...
>>
>> Any advices?
>>
>> Cheers.
>> --Thomas
>


--------------000503080607090109090408
Content-Type: text/plain;
name="masterDetailTestPatch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="masterDetailTestPatch.txt"

### Eclipse Workspace Patch 1.0
#P org.eclipse.emf.cdo.tests
Index: META-INF/MANIFEST.MF
============================================================ =======
RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/tests/ org.eclipse.emf.cdo.tests/META-INF/MANIFEST.MF,v
retrieving revision 1.62
diff -u -r1.62 MANIFEST.MF
--- META-INF/MANIFEST.MF 4 Feb 2010 16:59:27 -0000 1.62
+++ META-INF/MANIFEST.MF 23 Feb 2010 07:59:28 -0000
@@ -28,7 +28,9 @@
org.eclipse.emf.cdo.tests.model4;bundle-version="[3.0.0,4.0.0) ";visibility:=reexport,
org.eclipse.emf.cdo.tests.model4interfaces;bundle-version="[3.0.0,4.0.0) ";visibility:=reexport,
org.eclipse.emf.cdo.tests.model5;bundle-version="[3.0.0,4.0.0) ";visibility:=reexport,
- org.eclipse.emf.cdo.defs;bundle-version="[3.0.0,4.0.0)";visibility:=reexport
+ org.eclipse.emf.cdo.defs;bundle-version="[3.0.0,4.0.0)";visibility:=reexport,
+ org.eclipse.emf.databinding;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.core.databinding.property;bundle-version="1.2.0 "
Import-Package: org.apache.derby.jdbc;version="[10.0.0,11.0.0)",
org.h2.jdbcx;version="[1.1.0,1.2.0)"
Export-Package: base;version="3.0.0",
Index: src/org/eclipse/emf/cdo/tests/CdoDatabindingMasterDetailTest .java
============================================================ =======
RCS file: src/org/eclipse/emf/cdo/tests/CdoDatabindingMasterDetailTest .java
diff -N src/org/eclipse/emf/cdo/tests/CdoDatabindingMasterDetailTest .java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/emf/cdo/tests/CdoDatabindingMasterDetailTest .java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,164 @@
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.bundle.OM;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.model1.Customer;
+import org.eclipse.emf.cdo.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.Model1Package;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.emf.databinding.EMFProperties;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.list.IListChangeList ener;
+import org.eclipse.core.databinding.observable.list.IObservableList ;
+import org.eclipse.core.databinding.observable.list.ListChangeEvent ;
+import org.eclipse.core.databinding.observable.value.IObservableVal ue;
+import org.eclipse.core.databinding.observable.value.WritableValue;
+
+public class CdoDatabindingMasterDetailTest extends AbstractCDOTest
+{
+
+ private static final String RESOURCE_NAME = "resource";
+
+ private volatile boolean asyncUpdateFinished = false;
+
+ private volatile IObservableValue nameObservable = null;
+
+ private volatile Exception catchedException = null;
+
+ public void testMasterDetail() throws Exception
+ {
+ Realm testRealm = setupRealm();
+ setupInitialModel();
+ CDOSession session = openSession();
+
+ initRealm(testRealm, session);
+
+ assertNotNull(nameObservable);
+ assertNull(catchedException);
+
+ msg(nameObservable.getValue());
+
+ CDOTransaction transaction = session.openTransaction();
+ Company company = (Company)transaction.getResource("resource").getContents().get(0);
+ company.getCustomers().remove(0);
+
+ transaction.commit();
+
+ while (!asyncUpdateFinished)
+ {
+ synchronized (CdoDatabindingMasterDetailTest.this)
+ {
+ CdoDatabindingMasterDetailTest.this.wait();
+ }
+ }
+
+ assertNull(catchedException);
+
+ transaction.close();
+ session.close();
+ }
+
+ private void initRealm(Realm realm, final CDOSession session)
+ {
+ Realm.runWithDefault(realm, new Runnable()
+ {
+ public void run()
+ {
+ doBinding(session);
+ }
+ });
+ }
+
+ private void doBinding(CDOSession session)
+ {
+ msg("Setup binding");
+ CDOView view = session.openView();
+ view.options().addChangeSubscriptionPolicy(CDOAdapterPolicy. ALL);
+
+ // The master value will be selected from the company's customer list.
+ final Company company = (Company)view.getResource(RESOURCE_NAME).getContents().get(0 );
+ final WritableValue master = new WritableValue();
+
+ // The detail in test which will be observed is the customer's name.
+ nameObservable = EMFProperties.value(Model1Package.Literals.ADDRESS__NAME).ob serveDetail(master);
+
+ // Initially select the first customer from list.
+ master.setValue(company.getCustomers().get(0));
+
+ // Observe the company's customer list in order to detect list changes, i.e. remove of a customer. We have a simple
+ // approach here, whenever the list changes, the first customer is selected as master value.
+ IObservableList customers = EMFProperties.list(Model1Package.Literals.COMPANY__CUSTOMERS ).observe(company);
+ customers.addListChangeListener(new IListChangeListener()
+ {
+ public void handleListChange(ListChangeEvent event)
+ {
+ try
+ {
+ // Select the first customer from list
+ master.setValue(company.getCustomers().get(0));
+ }
+ catch (Exception e)
+ {
+ // This is the problem which is actually tested by this test. Because detail observable
+ // (DetailObservableValue) request the old value when they create a ValueDiff, an InvalidObjectException is
+ // thrown.
+ OM.LOG.error(e);
+ catchedException = e;
+ }
+ asyncUpdateFinished = true;
+ synchronized (CdoDatabindingMasterDetailTest.this)
+ {
+ CdoDatabindingMasterDetailTest.this.notifyAll();
+ }
+ }
+ });
+ }
+
+ private Realm setupRealm()
+ {
+ return new Realm()
+ {
+
+ @Override
+ public boolean isCurrent()
+ {
+ return true;
+ }
+ };
+ }
+
+ private void setupInitialModel()
+ {
+ // A company with two customers.
+ msg("Setting up initial model");
+ CDOSession session = openSession();
+
+ final CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(RESOURCE_NAME);
+
+ Company company = Model1Factory.eINSTANCE.createCompany();
+ company.setName("mycompany");
+
+ Customer customer1 = getModel1Factory().createCustomer();
+ customer1.setName("customer1");
+ Customer customer2 = getModel1Factory().createCustomer();
+ customer2.setName("customer2");
+
+ company.getCustomers().add(customer1);
+ company.getCustomers().add(customer2);
+
+ resource.getContents().add(company);
+
+ transaction.commit();
+
+ transaction.close();
+ session.close();
+ }
+
+}


--------------000503080607090109090408--
Re: [CDO databinding] [message #516233 is a reply to message #516206] Tue, 23 February 2010 10:18 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi Erwin,

Thanks. I had the possibility to chat with Matt today a bit and now that
we have the stack I hope we'll find a solution.

Not sure if we can get something into the core (if the core needs
fixing) because the API freeze is not far away.

Tom

Am 23.02.10 09:28, schrieb Erwin Betschart:
> Hi Tom
>
> I wrote a CDO testcase together with Thomas. I've attached a patch for
> the org.eclipse.emf.cdo.tests project.
>
> The problem is that databinding stores cdo object which can become
> invalid and throw runtime exceptions on access.
>
> [ERROR] Object OID4 is not valid in branch 0 at *
> org.eclipse.emf.cdo.util.InvalidObjectException: Object OID4 is not
> valid in branch 0 at *
> at
> org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1029)
>
> at
> org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1)
>
> at
> org.eclipse.net4j.util.fsm.FiniteStateMachine.process(Finite StateMachine.java:162)
>
> at
> org.eclipse.emf.internal.cdo.CDOStateMachine.read(CDOStateMa chine.java:322)
> at
> org.eclipse.emf.internal.cdo.CDOStore.getRevisionForReading( CDOStore.java:604)
>
> at org.eclipse.emf.internal.cdo.CDOStore.get(CDOStore.java:173)
> at
> org.eclipse.emf.internal.cdo.CDOObjectImpl.dynamicGet(CDOObj ectImpl.java:494)
>
> at
> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1986)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1037)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1021)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1013)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1008)
>
> at
> org.eclipse.emf.databinding.internal.EMFValueProperty.doGetV alue(EMFValueProperty.java:63)
>
> at
> org.eclipse.core.databinding.property.value.SimpleValuePrope rty.getValue(SimpleValueProperty.java:55)
>
> at
> org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.notifyIfChanged(SimplePropertyObserva bleValue.java:115)
>
> at
> org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.doGetValue(SimplePropertyObservableVa lue.java:97)
>
> at
> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.getValue(AbstractObservableValue.java:76)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$8.run(DetailObservableValue.java:142 )
>
> at
> org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue.doGetValue(DetailObservableValue.jav a:140)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$3.run(DetailObservableValue.java:88)
>
> at
> org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$2.handleValueChange(DetailObservable Value.java:86)
>
> at
> org.eclipse.core.databinding.observable.value.ValueChangeEve nt.dispatch(ValueChangeEvent.java:62)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.fireValueChange(AbstractObservableValue.java:71)
>
> at
> org.eclipse.core.databinding.observable.value.WritableValue. doSetValue(WritableValue.java:92)
>
> at
> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.setValue(AbstractObservableValue.java:55)
>
> at
> org.eclipse.emf.cdo.tests.CdoDatabindingMasterDetailTest$2.h andleListChange(CdoDatabindingMasterDetailTest.java:117)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>
> at
> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:112)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>
> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
> at
> org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
> at org.eclipse.core.databinding.observable.Realm.exec(Realm.jav a:170)
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$1.handleEvent(SimplePropertyObservableL ist.java:74)
>
> at
> org.eclipse.emf.databinding.internal.EMFPropertyListener$EMF ListPropertyListener.notifyChanged(EMFPropertyListener.java: 159)
>
> at
> org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify (BasicNotifierImpl.java:280)
>
> at
> org.eclipse.emf.common.notify.impl.NotificationImpl.dispatch (NotificationImpl.java:1033)
>
> at
> org.eclipse.emf.internal.cdo.view.CDOViewImpl.handleChangeSu bscription(CDOViewImpl.java:1469)
>
> at
> org.eclipse.emf.internal.cdo.view.CDOViewImpl.invalidate(CDO ViewImpl.java:1324)
>
> at
> org.eclipse.emf.internal.cdo.session.CDOSessionImpl$Invalida tionRunnable.run(CDOSessionImpl.java:1114)
>
> at
> org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:26)
> at
> org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:1)
> at
> org.eclipse.net4j.util.concurrent.QueueWorker.work(QueueWork er.java:64)
> at
> org.eclipse.net4j.util.concurrent.Worker$WorkerThread.run(Wo rker.java:188)
>
>
>
> Tom Schindl schrieb:
>> Hi Thomas,
>>
>> Can you at least provide a stacktrace for the master detail problem so
>> that we can see the offending method calls?
>>
>> Tom
>>
>> Am 18.02.10 18:13, schrieb Thomas Kowatsch:
>>> Hi.
>>>
>>> Is there anybody out there who is still working on a solution of this
>>> problem?
>>>
>>> Or at least thinking about a solution?
>>>
>>> This problem is essential to our project and our project will fail, if
>>> there is none, as we relied on the fact that databinding is working
>>> together with CDO.
>>>
>>> IMO it works excellent as long as you are working with one CDOView or
>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing is
>>> behaving very bad when you e.g. remove an object.
>>>
>>> One reason is that CDODeltaNotification is unable to deliver all needed
>>> data for databinding, i.e. on remove, the oldValue is just missing.
>>>
>>> Another reason is that when accessing an INVALID CDOObject, an exception
>>> is thrown.
>>>
>>> I tried to work araound those problems a bit, just to get it running.
>>> But when I solved one problem just one or more other come up.
>>>
>>> What I have done so far:
>>>
>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>> remove is called with a null (that is now fixed) or an empty collection
>>> element. I just wrote a custom ViewerUpdater that is passed to
>>> ObservableListContentProvider. I just did a refresh() in any case the
>>> needed information is missing. In my example here that would be if
>>> remove(Object element, int position) is called with an empty list, I do
>>> a refresh().
>>>
>>> - that worked quite ok, but then I had the next problem. We are having a
>>> master-detail situation and I followed the instructions from Tom's blog
>>> about EMF databinding. This uses a WriteableValue for the master
>>> observable. Everything worked quite ok, until the remote viewer (the
>>> viewer in the application that gets the remote remove notification) has
>>> currently selected the remotely removed element. In this case the
>>> WritableValue will get a value change because the selection of the
>>> viewer changes (the element was removed). Now a diff is created with the
>>> old, INVALID CDOObject as oldValue. Whenever this oldValue is accessed
>>> (or lets say an attribute of the oldValue) it will fail with the
>>> exception. So I though I overwrite two methods of WritableValue to solve
>>> this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
>>> fireValueChange() I check if the oldValue in the passed diff is an
>>> invalid object and if it is, I replace it with null and carry on with
>>> super.fireValueChange(). in doGetValue() I check if the cached value is
>>> an invalid object and return null in case. This solved the problems so
>>> far for all clients using the WritableValue or have a
>>> ValueChangedListener attached.
>>>
>>> - that is all ok and handable when it is in your program code. But if
>>> you use framework code you cannot overwrite this. The
>>> ...observeDetail(master) methods create DetailObservableValues that hold
>>> the master value as currentOuterValue. If this object is an INVALID
>>> CDOObject, then it fails when the master changes as in the
>>> outerChangeListener a doGetValue() is done at the beginning which tries
>>> to read an EAttribute from the INVALID object. I guess this happens
>>> throughout all databinding master-detail objects. For example, the label
>>> provider uses an attribute map to observe the attributes that are
>>> displayed by the LabelProvider, these are in generell
>>> DetailObservableValues which might access the INVALID object's
>>> attributes.
>>>
>>> At this point I decided to write this post, as I'm quite stuck and don't
>>> know how to proceed. I have no idea anymore how to solve that myself...
>>>
>>> Any advices?
>>>
>>> Cheers.
>>> --Thomas
>>
>
Re: [CDO databinding] [message #516748 is a reply to message #516233] Wed, 24 February 2010 23:48 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi Erwin,

Did you already filed a bug for this? Looking at the exception I think
we can solve this at the EMF-level. Please file a bug and file the
bug-id here.

I'll then coordinate the solution with the different project owners
(EMF-DB, CDO, CORE-DB).

Tom

Am 23.02.10 11:18, schrieb Tom Schindl:
> Hi Erwin,
>
> Thanks. I had the possibility to chat with Matt today a bit and now that
> we have the stack I hope we'll find a solution.
>
> Not sure if we can get something into the core (if the core needs
> fixing) because the API freeze is not far away.
>
> Tom
>
> Am 23.02.10 09:28, schrieb Erwin Betschart:
>> Hi Tom
>>
>> I wrote a CDO testcase together with Thomas. I've attached a patch for
>> the org.eclipse.emf.cdo.tests project.
>>
>> The problem is that databinding stores cdo object which can become
>> invalid and throw runtime exceptions on access.
>>
>> [ERROR] Object OID4 is not valid in branch 0 at *
>> org.eclipse.emf.cdo.util.InvalidObjectException: Object OID4 is not
>> valid in branch 0 at *
>> at
>> org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1029)
>>
>> at
>> org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1)
>>
>> at
>> org.eclipse.net4j.util.fsm.FiniteStateMachine.process(Finite StateMachine.java:162)
>>
>> at
>> org.eclipse.emf.internal.cdo.CDOStateMachine.read(CDOStateMa chine.java:322)
>> at
>> org.eclipse.emf.internal.cdo.CDOStore.getRevisionForReading( CDOStore.java:604)
>>
>> at org.eclipse.emf.internal.cdo.CDOStore.get(CDOStore.java:173)
>> at
>> org.eclipse.emf.internal.cdo.CDOObjectImpl.dynamicGet(CDOObj ectImpl.java:494)
>>
>> at
>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1986)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1037)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1021)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1013)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1008)
>>
>> at
>> org.eclipse.emf.databinding.internal.EMFValueProperty.doGetV alue(EMFValueProperty.java:63)
>>
>> at
>> org.eclipse.core.databinding.property.value.SimpleValuePrope rty.getValue(SimpleValueProperty.java:55)
>>
>> at
>> org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.notifyIfChanged(SimplePropertyObserva bleValue.java:115)
>>
>> at
>> org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.doGetValue(SimplePropertyObservableVa lue.java:97)
>>
>> at
>> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.getValue(AbstractObservableValue.java:76)
>>
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$8.run(DetailObservableValue.java:142 )
>>
>> at
>> org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
>>
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue.doGetValue(DetailObservableValue.jav a:140)
>>
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$3.run(DetailObservableValue.java:88)
>>
>> at
>> org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
>>
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$2.handleValueChange(DetailObservable Value.java:86)
>>
>> at
>> org.eclipse.core.databinding.observable.value.ValueChangeEve nt.dispatch(ValueChangeEvent.java:62)
>>
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>>
>> at
>> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.fireValueChange(AbstractObservableValue.java:71)
>>
>> at
>> org.eclipse.core.databinding.observable.value.WritableValue. doSetValue(WritableValue.java:92)
>>
>> at
>> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.setValue(AbstractObservableValue.java:55)
>>
>> at
>> org.eclipse.emf.cdo.tests.CdoDatabindingMasterDetailTest$2.h andleListChange(CdoDatabindingMasterDetailTest.java:117)
>>
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>>
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>>
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>>
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>>
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>>
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>>
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>>
>> at
>> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>>
>> at
>> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:112)
>>
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>>
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>>
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>>
>> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
>> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
>> at
>> org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
>> at org.eclipse.core.databinding.observable.Realm.exec(Realm.jav a:170)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$1.handleEvent(SimplePropertyObservableL ist.java:74)
>>
>> at
>> org.eclipse.emf.databinding.internal.EMFPropertyListener$EMF ListPropertyListener.notifyChanged(EMFPropertyListener.java: 159)
>>
>> at
>> org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify (BasicNotifierImpl.java:280)
>>
>> at
>> org.eclipse.emf.common.notify.impl.NotificationImpl.dispatch (NotificationImpl.java:1033)
>>
>> at
>> org.eclipse.emf.internal.cdo.view.CDOViewImpl.handleChangeSu bscription(CDOViewImpl.java:1469)
>>
>> at
>> org.eclipse.emf.internal.cdo.view.CDOViewImpl.invalidate(CDO ViewImpl.java:1324)
>>
>> at
>> org.eclipse.emf.internal.cdo.session.CDOSessionImpl$Invalida tionRunnable.run(CDOSessionImpl.java:1114)
>>
>> at
>> org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:26)
>> at
>> org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:1)
>> at
>> org.eclipse.net4j.util.concurrent.QueueWorker.work(QueueWork er.java:64)
>> at
>> org.eclipse.net4j.util.concurrent.Worker$WorkerThread.run(Wo rker.java:188)
>>
>>
>>
>> Tom Schindl schrieb:
>>> Hi Thomas,
>>>
>>> Can you at least provide a stacktrace for the master detail problem so
>>> that we can see the offending method calls?
>>>
>>> Tom
>>>
>>> Am 18.02.10 18:13, schrieb Thomas Kowatsch:
>>>> Hi.
>>>>
>>>> Is there anybody out there who is still working on a solution of this
>>>> problem?
>>>>
>>>> Or at least thinking about a solution?
>>>>
>>>> This problem is essential to our project and our project will fail, if
>>>> there is none, as we relied on the fact that databinding is working
>>>> together with CDO.
>>>>
>>>> IMO it works excellent as long as you are working with one CDOView or
>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing is
>>>> behaving very bad when you e.g. remove an object.
>>>>
>>>> One reason is that CDODeltaNotification is unable to deliver all needed
>>>> data for databinding, i.e. on remove, the oldValue is just missing.
>>>>
>>>> Another reason is that when accessing an INVALID CDOObject, an exception
>>>> is thrown.
>>>>
>>>> I tried to work araound those problems a bit, just to get it running.
>>>> But when I solved one problem just one or more other come up.
>>>>
>>>> What I have done so far:
>>>>
>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>> remove is called with a null (that is now fixed) or an empty collection
>>>> element. I just wrote a custom ViewerUpdater that is passed to
>>>> ObservableListContentProvider. I just did a refresh() in any case the
>>>> needed information is missing. In my example here that would be if
>>>> remove(Object element, int position) is called with an empty list, I do
>>>> a refresh().
>>>>
>>>> - that worked quite ok, but then I had the next problem. We are having a
>>>> master-detail situation and I followed the instructions from Tom's blog
>>>> about EMF databinding. This uses a WriteableValue for the master
>>>> observable. Everything worked quite ok, until the remote viewer (the
>>>> viewer in the application that gets the remote remove notification) has
>>>> currently selected the remotely removed element. In this case the
>>>> WritableValue will get a value change because the selection of the
>>>> viewer changes (the element was removed). Now a diff is created with the
>>>> old, INVALID CDOObject as oldValue. Whenever this oldValue is accessed
>>>> (or lets say an attribute of the oldValue) it will fail with the
>>>> exception. So I though I overwrite two methods of WritableValue to solve
>>>> this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
>>>> fireValueChange() I check if the oldValue in the passed diff is an
>>>> invalid object and if it is, I replace it with null and carry on with
>>>> super.fireValueChange(). in doGetValue() I check if the cached value is
>>>> an invalid object and return null in case. This solved the problems so
>>>> far for all clients using the WritableValue or have a
>>>> ValueChangedListener attached.
>>>>
>>>> - that is all ok and handable when it is in your program code. But if
>>>> you use framework code you cannot overwrite this. The
>>>> ...observeDetail(master) methods create DetailObservableValues that hold
>>>> the master value as currentOuterValue. If this object is an INVALID
>>>> CDOObject, then it fails when the master changes as in the
>>>> outerChangeListener a doGetValue() is done at the beginning which tries
>>>> to read an EAttribute from the INVALID object. I guess this happens
>>>> throughout all databinding master-detail objects. For example, the label
>>>> provider uses an attribute map to observe the attributes that are
>>>> displayed by the LabelProvider, these are in generell
>>>> DetailObservableValues which might access the INVALID object's
>>>> attributes.
>>>>
>>>> At this point I decided to write this post, as I'm quite stuck and don't
>>>> know how to proceed. I have no idea anymore how to solve that myself...
>>>>
>>>> Any advices?
>>>>
>>>> Cheers.
>>>> --Thomas
>>>
>>
>
Re: [CDO databinding] [message #516793 is a reply to message #516748] Thu, 25 February 2010 08:31 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Hi Tom.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=303868
Cheers
--Thomas

Tom Schindl schrieb:
> Hi Erwin,
>
> Did you already filed a bug for this? Looking at the exception I think
> we can solve this at the EMF-level. Please file a bug and file the
> bug-id here.
>
> I'll then coordinate the solution with the different project owners
> (EMF-DB, CDO, CORE-DB).
>
> Tom
>
> Am 23.02.10 11:18, schrieb Tom Schindl:
>> Hi Erwin,
>>
>> Thanks. I had the possibility to chat with Matt today a bit and now that
>> we have the stack I hope we'll find a solution.
>>
>> Not sure if we can get something into the core (if the core needs
>> fixing) because the API freeze is not far away.
>>
>> Tom
>>
>> Am 23.02.10 09:28, schrieb Erwin Betschart:
>>> Hi Tom
>>>
>>> I wrote a CDO testcase together with Thomas. I've attached a patch for
>>> the org.eclipse.emf.cdo.tests project.
>>>
>>> The problem is that databinding stores cdo object which can become
>>> invalid and throw runtime exceptions on access.
>>>
>>> [ERROR] Object OID4 is not valid in branch 0 at *
>>> org.eclipse.emf.cdo.util.InvalidObjectException: Object OID4 is not
>>> valid in branch 0 at *
>>> at
>>> org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1029)
>>>
>>> at
>>> org.eclipse.emf.internal.cdo.CDOStateMachine$InvalidTransiti on.execute(CDOStateMachine.java:1)
>>>
>>> at
>>> org.eclipse.net4j.util.fsm.FiniteStateMachine.process(Finite StateMachine.java:162)
>>>
>>> at
>>> org.eclipse.emf.internal.cdo.CDOStateMachine.read(CDOStateMa chine.java:322)
>>> at
>>> org.eclipse.emf.internal.cdo.CDOStore.getRevisionForReading( CDOStore.java:604)
>>>
>>> at org.eclipse.emf.internal.cdo.CDOStore.get(CDOStore.java:173)
>>> at
>>> org.eclipse.emf.internal.cdo.CDOObjectImpl.dynamicGet(CDOObj ectImpl.java:494)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1986)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1037)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1021)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1013)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1008)
>>>
>>> at
>>> org.eclipse.emf.databinding.internal.EMFValueProperty.doGetV alue(EMFValueProperty.java:63)
>>>
>>> at
>>> org.eclipse.core.databinding.property.value.SimpleValuePrope rty.getValue(SimpleValueProperty.java:55)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.notifyIfChanged(SimplePropertyObserva bleValue.java:115)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.property.value.SimpleP ropertyObservableValue.doGetValue(SimplePropertyObservableVa lue.java:97)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.getValue(AbstractObservableValue.java:76)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$8.run(DetailObservableValue.java:142 )
>>>
>>> at
>>> org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue.doGetValue(DetailObservableValue.jav a:140)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$3.run(DetailObservableValue.java:88)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.ObservableTracker.ru nAndIgnore(ObservableTracker.java:169)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue$2.handleValueChange(DetailObservable Value.java:86)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.value.ValueChangeEve nt.dispatch(ValueChangeEvent.java:62)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.fireValueChange(AbstractObservableValue.java:71)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.value.WritableValue. doSetValue(WritableValue.java:92)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.value.AbstractObserv ableValue.setValue(AbstractObservableValue.java:55)
>>>
>>> at
>>> org.eclipse.emf.cdo.tests.CdoDatabindingMasterDetailTest$2.h andleListChange(CdoDatabindingMasterDetailTest.java:117)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>>>
>>> at
>>> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:112)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>>>
>>> at
>>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>>>
>>> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
>>> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
>>> at
>>> org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
>>> at org.eclipse.core.databinding.observable.Realm.exec(Realm.jav a:170)
>>> at
>>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$1.handleEvent(SimplePropertyObservableL ist.java:74)
>>>
>>> at
>>> org.eclipse.emf.databinding.internal.EMFPropertyListener$EMF ListPropertyListener.notifyChanged(EMFPropertyListener.java: 159)
>>>
>>> at
>>> org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify (BasicNotifierImpl.java:280)
>>>
>>> at
>>> org.eclipse.emf.common.notify.impl.NotificationImpl.dispatch (NotificationImpl.java:1033)
>>>
>>> at
>>> org.eclipse.emf.internal.cdo.view.CDOViewImpl.handleChangeSu bscription(CDOViewImpl.java:1469)
>>>
>>> at
>>> org.eclipse.emf.internal.cdo.view.CDOViewImpl.invalidate(CDO ViewImpl.java:1324)
>>>
>>> at
>>> org.eclipse.emf.internal.cdo.session.CDOSessionImpl$Invalida tionRunnable.run(CDOSessionImpl.java:1114)
>>>
>>> at
>>> org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:26)
>>> at
>>> org.eclipse.net4j.util.concurrent.QueueRunner.work(QueueRunn er.java:1)
>>> at
>>> org.eclipse.net4j.util.concurrent.QueueWorker.work(QueueWork er.java:64)
>>> at
>>> org.eclipse.net4j.util.concurrent.Worker$WorkerThread.run(Wo rker.java:188)
>>>
>>>
>>>
>>> Tom Schindl schrieb:
>>>> Hi Thomas,
>>>>
>>>> Can you at least provide a stacktrace for the master detail problem so
>>>> that we can see the offending method calls?
>>>>
>>>> Tom
>>>>
>>>> Am 18.02.10 18:13, schrieb Thomas Kowatsch:
>>>>> Hi.
>>>>>
>>>>> Is there anybody out there who is still working on a solution of this
>>>>> problem?
>>>>>
>>>>> Or at least thinking about a solution?
>>>>>
>>>>> This problem is essential to our project and our project will fail, if
>>>>> there is none, as we relied on the fact that databinding is working
>>>>> together with CDO.
>>>>>
>>>>> IMO it works excellent as long as you are working with one CDOView or
>>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing is
>>>>> behaving very bad when you e.g. remove an object.
>>>>>
>>>>> One reason is that CDODeltaNotification is unable to deliver all needed
>>>>> data for databinding, i.e. on remove, the oldValue is just missing.
>>>>>
>>>>> Another reason is that when accessing an INVALID CDOObject, an exception
>>>>> is thrown.
>>>>>
>>>>> I tried to work araound those problems a bit, just to get it running.
>>>>> But when I solved one problem just one or more other come up.
>>>>>
>>>>> What I have done so far:
>>>>>
>>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>>> remove is called with a null (that is now fixed) or an empty collection
>>>>> element. I just wrote a custom ViewerUpdater that is passed to
>>>>> ObservableListContentProvider. I just did a refresh() in any case the
>>>>> needed information is missing. In my example here that would be if
>>>>> remove(Object element, int position) is called with an empty list, I do
>>>>> a refresh().
>>>>>
>>>>> - that worked quite ok, but then I had the next problem. We are having a
>>>>> master-detail situation and I followed the instructions from Tom's blog
>>>>> about EMF databinding. This uses a WriteableValue for the master
>>>>> observable. Everything worked quite ok, until the remote viewer (the
>>>>> viewer in the application that gets the remote remove notification) has
>>>>> currently selected the remotely removed element. In this case the
>>>>> WritableValue will get a value change because the selection of the
>>>>> viewer changes (the element was removed). Now a diff is created with the
>>>>> old, INVALID CDOObject as oldValue. Whenever this oldValue is accessed
>>>>> (or lets say an attribute of the oldValue) it will fail with the
>>>>> exception. So I though I overwrite two methods of WritableValue to solve
>>>>> this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
>>>>> fireValueChange() I check if the oldValue in the passed diff is an
>>>>> invalid object and if it is, I replace it with null and carry on with
>>>>> super.fireValueChange(). in doGetValue() I check if the cached value is
>>>>> an invalid object and return null in case. This solved the problems so
>>>>> far for all clients using the WritableValue or have a
>>>>> ValueChangedListener attached.
>>>>>
>>>>> - that is all ok and handable when it is in your program code. But if
>>>>> you use framework code you cannot overwrite this. The
>>>>> ...observeDetail(master) methods create DetailObservableValues that hold
>>>>> the master value as currentOuterValue. If this object is an INVALID
>>>>> CDOObject, then it fails when the master changes as in the
>>>>> outerChangeListener a doGetValue() is done at the beginning which tries
>>>>> to read an EAttribute from the INVALID object. I guess this happens
>>>>> throughout all databinding master-detail objects. For example, the label
>>>>> provider uses an attribute map to observe the attributes that are
>>>>> displayed by the LabelProvider, these are in generell
>>>>> DetailObservableValues which might access the INVALID object's
>>>>> attributes.
>>>>>
>>>>> At this point I decided to write this post, as I'm quite stuck and don't
>>>>> know how to proceed. I have no idea anymore how to solve that myself...
>>>>>
>>>>> Any advices?
>>>>>
>>>>> Cheers.
>>>>> --Thomas
>
Re: [CDO databinding] [message #526402 is a reply to message #510385] Sat, 10 April 2010 12:43 Go to previous messageGo to next message
Joel Rosi-Schwartz is currently offline Joel Rosi-SchwartzFriend
Messages: 624
Registered: July 2009
Location: London. England
Senior Member
Hi,

From this thread trailing off and Bug 303868 still in NEW, I am assuming that this is not going to get addressed in the Helios release. Is that accurate?

Joel
Re: [CDO databinding] [message #526411 is a reply to message #526402] Sat, 10 April 2010 15:10 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33218
Registered: July 2009
Senior Member
Joel,

Tom was hoping to have time to look into it this weekend. It's best to
follow up on the bugzilla itself...


Joel Rosi-Schwartz wrote:
> Hi,
>
> From this thread trailing off and Bug 303868 still in NEW, I am
> assuming that this is not going to get addressed in the Helios
> release. Is that accurate?
> Joel


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [CDO databinding] [message #526560 is a reply to message #526411] Mon, 12 April 2010 09:37 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
My e4 duties kept me away from EMF-Databinding this weekend but I just
commented on the bug.

I guess what we need is test cases to reproduce the different CDO
exceptions so that we can spot the areas in Eclipse Databinding.

Tom

Am 10.04.10 17:10, schrieb Ed Merks:
> Joel,
>
> Tom was hoping to have time to look into it this weekend. It's best to
> follow up on the bugzilla itself...
>
>
> Joel Rosi-Schwartz wrote:
>> Hi,
>>
>> From this thread trailing off and Bug 303868 still in NEW, I am
>> assuming that this is not going to get addressed in the Helios
>> release. Is that accurate?
>> Joel
Re: [CDO databinding] [message #526572 is a reply to message #526560] Mon, 12 April 2010 10:22 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Thomas.Kowatsch.ruag.com

Hi Tom.

Nice to hear that something is moving now around this problem.

Unfortunately, I have no time at the moment (until end of month) to
provide you with some useful testcases, as our project is in the final
stage.
But anyway, as Eike now provides old values in (nearly) any case, it is
all about handling or accessing data of INVALID objects.
Problems can occur nearly everywhere, where a featured attribute is used
or on lists/sets/maps, when the list contains INVALID objects.
Another one I found is also for example on EcoreElists#contains(object).
If the passed object is an invalid object this will fail. contains() is
called very often also from the Collections framework, e.g. a
removeAll(..) could call contains on either the collection itself or the
one passed as argument!
Another problem could be all Observable...ContentProvider as they also
work very intensiv with Collections containing INVALID objects...
Master Detail observables/properties must be considered also.

--Thomas

Tom Schindl schrieb:
> My e4 duties kept me away from EMF-Databinding this weekend but I just
> commented on the bug.
>
> I guess what we need is test cases to reproduce the different CDO
> exceptions so that we can spot the areas in Eclipse Databinding.
>
> Tom
>
> Am 10.04.10 17:10, schrieb Ed Merks:
>> Joel,
>>
>> Tom was hoping to have time to look into it this weekend. It's best to
>> follow up on the bugzilla itself...
>>
>>
>> Joel Rosi-Schwartz wrote:
>>> Hi,
>>>
>>> From this thread trailing off and Bug 303868 still in NEW, I am
>>> assuming that this is not going to get addressed in the Helios
>>> release. Is that accurate?
>>> Joel
>
Re: [CDO databinding] [message #526603 is a reply to message #526572] Mon, 12 April 2010 11:51 Go to previous message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6690
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------030408090108030407090601
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

Guys,

One remark. Some time ago Ed asked me whether we change the behaviour of
equals() and hashCode(). We don't:

| /**
* Specializing the behaviour of {@link #hashCode()}
is not permitted as per {@link EObject} specification.
*/
@Override
*public final **int *hashCode()
{
*return super*.hashCode();
}

/**
* Specializing the behaviour of {@link #equals(Object)}
is not permitted as per {@link EObject} specification.
*/
@Override
*public final **boolean *equals(Object obj)
{
*return super*.equals(obj);
}|


Cheers
/Eike

----
http://thegordian.blogspot.com
http://twitter.com/eikestepper



Am 12.04.2010 12:22, schrieb Thomas Kowatsch:
> Hi Tom.
>
> Nice to hear that something is moving now around this problem.
>
> Unfortunately, I have no time at the moment (until end of month) to
> provide you with some useful testcases, as our project is in the final
> stage.
> But anyway, as Eike now provides old values in (nearly) any case, it
> is all about handling or accessing data of INVALID objects.
> Problems can occur nearly everywhere, where a featured attribute is
> used or on lists/sets/maps, when the list contains INVALID objects.
> Another one I found is also for example on
> EcoreElists#contains(object). If the passed object is an invalid
> object this will fail. contains() is called very often also from the
> Collections framework, e.g. a removeAll(..) could call contains on
> either the collection itself or the one passed as argument!
> Another problem could be all Observable...ContentProvider as they also
> work very intensiv with Collections containing INVALID objects...
> Master Detail observables/properties must be considered also.
>
> --Thomas
>
> Tom Schindl schrieb:
>> My e4 duties kept me away from EMF-Databinding this weekend but I just
>> commented on the bug.
>>
>> I guess what we need is test cases to reproduce the different CDO
>> exceptions so that we can spot the areas in Eclipse Databinding.
>>
>> Tom
>>
>> Am 10.04.10 17:10, schrieb Ed Merks:
>>> Joel,
>>>
>>> Tom was hoping to have time to look into it this weekend. It's best to
>>> follow up on the bugzilla itself...
>>>
>>>
>>> Joel Rosi-Schwartz wrote:
>>>> Hi,
>>>>
>>>> From this thread trailing off and Bug 303868 still in NEW, I am
>>>> assuming that this is not going to get addressed in the Helios
>>>> release. Is that accurate?
>>>> Joel
>>

--------------030408090108030407090601
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Guys,<br>
<br>
One remark. Some time ago Ed asked me whether we change the behaviour
of equals() and hashCode(). We don't:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#ffffff">  </font><font
color="#3f5fbf">/**</font><br>
<font color="#ffffff">   </font><font color="#3f5fbf">* Specializing the behaviour of </font ><font
color="#3f3fbf">{@link #hashCode()} </font><font color="#3f5fbf">is not permitted as per </font><font
color="#3f3fbf">{@link EObject} </font><font color="#3f5fbf">specification.</font><br>
<font color="#ffffff">   </font><font color="#3f5fbf">*/</font><br>
<font color="#ffffff">  </font><font color="#646464">@Override</font><br>
<font color="#ffffff">  </font><font color="#7f0055"><b>public final </b></font><font
color="#7f0055"><b>int </b></font><font color="#000000">hashCode</font><font
color="#000000">()</font><br>
<font color="#ffffff">  </font><font color="#000000">{</font><br>
<font color="#ffffff">    </font><font color="#7f0055"><b>return super</b></font><font
color="#000000">.hashCode</font><font color="#000000">()</font><font
color="#000000">;</font><br>
<font color="#ffffff">  </font><font color="#000000">}</font><br>
<font color="#ffffff"></font><br>
<font color="#ffffff">  </font><font color="#3f5fbf">/**</font><br>
<font color="#ffffff">   </font><font color="#3f5fbf">* Specializing the behaviour of </font ><font
color="#3f3fbf">{@link #equals(Object)} </font><font color="#3f5fbf">is not permitted as per </font><font
color="#3f3fbf">{@link EObject} </font><font color="#3f5fbf">specification.</font><br>
<font color="#ffffff">   </font><font color="#3f5fbf">*/</font><br>
<font color="#ffffff">  </font><font color="#646464">@Override</font><br>
<font color="#ffffff">  </font><font color="#7f0055"><b>public final </b></font><font
color="#7f0055"><b>boolean </b></font><font color="#000000">equals</font><font
color="#000000">(</font><font color="#000000">Object obj</font><font
color="#000000">)</font><br>
<font color="#ffffff">  </font><font color="#000000">{</font><br>
<font color="#ffffff">    </font><font color="#7f0055"><b>return super</b></font><font
color="#000000">.equals</font><font color="#000000">(</font><font
color="#000000">obj</font><font color="#000000">)</font><font
color="#000000">;</font><br>
<font color="#ffffff">  </font><font color="#000000">}</font></code>
</td>
<!-- end source code --> </tr>
</tbody>
</table>
</div>
<!-- = END of automatically generated HTML code = -->
<!-- ======================================================== --><br>
Cheers<br>
/Eike<br>
<br>
----<br>
<a class="moz-txt-link-freetext" href="http://thegordian.blogspot.com">http://thegordian.blogspot.com</a><br>
<a class="moz-txt-link-freetext" href="http://twitter.com/eikestepper">http://twitter.com/eikestepper</a><br>
<br>
<br>
<br>
Am 12.04.2010 12:22, schrieb Thomas Kowatsch:
<blockquote cite="mid:hpus91$vhq$1@build.eclipse.org" type="cite">Hi
Tom.
<br>
<br>
Nice to hear that something is moving now around this problem.
<br>
<br>
Unfortunately, I have no time at the moment (until end of month) to
provide you with some useful testcases, as our project is in the final
stage.
<br>
But anyway, as Eike now provides old values in (nearly) any case, it is
all about handling or accessing data of INVALID objects.
<br>
Problems can occur nearly everywhere, where a featured attribute is
used or on lists/sets/maps, when the list contains INVALID objects.
<br>
Another one I found is also for example on
EcoreElists#contains(object). If the passed object is an invalid object
this will fail. contains() is called very often also from the
Collections framework, e.g. a removeAll(..) could call contains on
either the collection itself or the one passed as argument!
<br>
Another problem could be all Observable...ContentProvider as they also
work very intensiv with Collections containing INVALID objects...
<br>
Master Detail observables/properties must be considered also.
<br>
<br>
--Thomas
<br>
<br>
Tom Schindl schrieb:
<br>
<blockquote type="cite">My e4 duties kept me away from
EMF-Databinding this weekend but I just
<br>
commented on the bug.
<br>
<br>
I guess what we need is test cases to reproduce the different CDO
<br>
exceptions so that we can spot the areas in Eclipse Databinding.
<br>
<br>
Tom
<br>
<br>
Am 10.04.10 17:10, schrieb Ed Merks:
<br>
<blockquote type="cite">Joel,
<br>
<br>
Tom was hoping to have time to look into it this weekend.  It's best to
<br>
follow up on the bugzilla itself...
<br>
<br>
<br>
Joel Rosi-Schwartz wrote:
<br>
<blockquote type="cite">Hi,
<br>
<br>
From this thread trailing off and Bug 303868 still in NEW, I am
<br>
assuming that this is not going to get addressed in the Helios
<br>
release. Is that accurate?
<br>
Joel
<br>
</blockquote>
</blockquote>
<br>
</blockquote>
</blockquote>
</body>
</html>

--------------030408090108030407090601--


Previous Topic:XTEXT: xmi file generation
Next Topic:[CDO] Model Corruption ClassCastException Server Side
Goto Forum:
  


Current Time: Wed Sep 25 23:39:24 GMT 2024

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

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

Back to the top