Home » Modeling » EMF » [CDO databinding]
[CDO databinding] [message #510385] |
Wed, 27 January 2010 07:26 |
Eclipse User |
|
|
|
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 |
Eclipse User |
|
|
|
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 |
Thomas Schindl 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 |
Eclipse User |
|
|
|
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 #510409 is a reply to message #510404] |
Wed, 27 January 2010 13:16 |
Eclipse User |
|
|
|
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 |
Eclipse User |
|
|
|
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 #510422 is a reply to message #510420] |
Wed, 27 January 2010 13:58 |
Eclipse User |
|
|
|
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 |
Eclipse User |
|
|
|
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 #510671 is a reply to message #510385] |
Thu, 28 January 2010 09:46 |
|
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>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| | | |
Re: [CDO databinding] [message #510675 is a reply to message #510671] |
Thu, 28 January 2010 10:25 |
Eclipse User |
|
|
|
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 #510692 is a reply to message #510690] |
Thu, 28 January 2010 06:02 |
Eclipse User |
|
|
|
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 |
Eclipse User |
|
|
|
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 |
|
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
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Re: [CDO databinding] [message #510731 is a reply to message #510720] |
Thu, 28 January 2010 08:34 |
|
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
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #510753 is a reply to message #510731] |
Thu, 28 January 2010 09:46 |
Thomas Schindl 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 |
|
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
>>>
>>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #510800 is a reply to message #510754] |
Thu, 28 January 2010 11:52 |
Ed Merks 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 |
|
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
>>>>>
>>>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #510874 is a reply to message #510385] |
Thu, 28 January 2010 22:30 |
Boris Bokowski 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 |
|
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
>>
>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #511595 is a reply to message #510754] |
Tue, 02 February 2010 08:30 |
Thomas Schindl 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 |
Thomas Schindl 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 |
|
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">
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #515416 is a reply to message #510385] |
Thu, 18 February 2010 12:46 |
Eclipse User |
|
|
|
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 |
|
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
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #515425 is a reply to message #515417] |
Thu, 18 February 2010 13:16 |
Eclipse User |
|
|
|
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 |
Thomas Schindl 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 |
|
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
>>>>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #515523 is a reply to message #515426] |
Fri, 19 February 2010 04:26 |
Eclipse User |
|
|
|
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 |
|
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
>>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO databinding] [message #515539 is a reply to message #515524] |
Fri, 19 February 2010 10:09 |
Thomas Schindl 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 #515564 is a reply to message #515560] |
Fri, 19 February 2010 11:21 |
Eclipse User |
|
|
|
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 #515585 is a reply to message #515565] |
Fri, 19 February 2010 08:12 |
|
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
>>>
>>>
>>>
>
Cheers
/Eike
----
http://www.esc-net.de
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 |
Thomas Schindl 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 |
Erwin Betschart 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 |
Thomas Schindl 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 |
Thomas Schindl 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 |
Eclipse User |
|
|
|
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 |
|
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 |
Eclipse User |
|
|
|
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 |
|
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--
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Goto Forum:
Current Time: Wed Sep 25 23:39:24 GMT 2024
Powered by FUDForum. Page generated in 0.15303 seconds
|