Home » Modeling » EMF » [CDO databinding]
| [CDO databinding] [message #510385] |
Wed, 27 January 2010 02: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 #510392 is a reply to message #510385] |
Wed, 27 January 2010 07:30   |
Eclipse User |
|
|
|
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 #510671 is a reply to message #510385] |
Thu, 28 January 2010 04:46   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------060305060907050103000402
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit
Hey Guys,
I was out of office, so I chime in late. More comments below...
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Thomas Kowatsch schrieb:
> Hi,
>
> I'm using EMF, CDO and databinding. I have a master detail scenario
> with a viewer and a detail part. I just was testing what happens when
> I have opened the application twice to see how the notification and
> update runs.
>
> Now I ran into the problem, that when I delete an entry in Appl1, it
> crashes in Appl2 when the viewer is refreshed from the
> ObservableListContentProvider. Here the stack trace:
>
>
> org.eclipse.core.runtime.AssertionFailedException: null argument:
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
> at
> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
>
> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
> at
> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
>
> at
> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
>
> at
> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
>
> at
> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>
> at
> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
>
> at
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
>
> at
> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>
> at
> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>
> at
> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>
> at
> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>
> at
> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>
> at
> org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
> at
> org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
> at
> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
>
> at
> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
>
> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
> at
> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
>
> at
> org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
> at
> org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
> ....
>
> So it seems that a "null" object is delivered to the viewer. I tried
> to track it down further and ended up in
> EMFListPropertyListener#notifyChanged(Notification). In the switch at
> case "Notification.REMOVE",
Shouldn't that be REMOVE_MANY?
> a list diff is created with
> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(),
> false, msg.getOldValue())). Now I guess the problem is that
> msg.getOldValue() returns null!
As per JavaDoc in CDODeltaNotification CDO does not provide old values:
| * This *class *behaves like the usual EMF Notification except *for *the following:
* <ul>
* <li>It doesn't provide the old value, only the *new *index or *new *value.
* <li>{@link Notification#REMOVE_MANY REMOVE_MANY} indicates that {@link Collection#clear() clear()} was called.
* <li>{@link Notification#Add_MANY Add_MANY} is not used.
* </ul>|
The reason was/is that the old value is usually rarely used and very
expensive to determine and transfer by CDO in advance (i.e. with the
original CommitNotificationRequest). After the original notification it
would be impossible to lazily request it from the server if audfiting is
not enabled in the repository. We *could* discuss an enhancement in the
change subscription options so that there is a third option beside
ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
(needed per object?, etc...) and quite some effort. to implement. Before
we even consider this discussion I'd like to understand what exactly the
old values are used for by data binding.
Is it true that the old values are only used to push some undo
information to a command stack or so? This would IMO be questionable
anyway, because I doubt that changes of a remote user should be undoable
at all. Maybe we some specialized logic in the databinding that treats
CDODeltaNotifications (instanceof check) differently from normal EMF
Notifications. The new values should be set into the UI, but these
changes should not be undoable. Opinions?
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
>
> I checked that also in Appl1 (in the same CDOView that the element is
> deleted) and saw that msg.getOldValue() returns the deleted object.
>
> Is this actually a bug? If not then IMHO CDO and databinding is not
> usable as is.
>
> Cheers.
> --Thomas
--------------060305060907050103000402
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hey Guys,<br>
<br>
I was out of office, so I chime in late. More comments below...<br>
<br>
Cheers<br>
/Eike<br>
<br>
----<br>
<a class="moz-txt-link-freetext" href="http://thegordian.blogspot.com">http://thegordian.blogspot.com</a><br>
<a class="moz-txt-link-freetext" href="http://twitter.com/eikestepper">http://twitter.com/eikestepper</a><br>
<br>
<br>
<br>
<br>
Thomas Kowatsch schrieb:
<blockquote cite="mid:hjpaqo$e12$1@build.eclipse.org" type="cite">Hi,
<br>
<br>
I'm using EMF, CDO and databinding. I have a master detail scenario
with a viewer and a detail part. I just was testing what happens when I
have opened the application twice to see how the notification and
update runs.
<br>
<br>
Now I ran into the problem, that when I delete an entry in Appl1, it
crashes in Appl2 when the viewer is refreshed from the
ObservableListContentProvider. Here the stack trace:
<br>
<br>
<br>
org.eclipse.core.runtime.AssertionFailedException: null argument:
<br>
|
|
| | | | | | | | | | | | |
| Re: [CDO databinding] [message #510753 is a reply to message #510731] |
Thu, 28 January 2010 04:46   |
Eclipse User |
|
|
|
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 04:46   |
Eclipse User |
|
|
|
Hi Tom,
I start to understand the "influences" although I don't have a solution
yet. Another thing I just realized is, that we (I at least) so far
talked about *detached* objects, i.e. elements of many-valued
*containment* features. I suspect the same problem occurs with removals
from cross references.
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Tom Schindl schrieb:
> Well the one that is in charge of this is list is out-of-scope for
> EMF-Databinding because the only thing it knows is that someone is
> observeing it and it informs this observe through a change-event (which
> holds the missleading diff)
>
> The only one who could do this scan in the case is JFace-Databinding
> which naturally has no idea about CDO, EMF, ... (in general about the
> domain technology) because from its point of view it only attaches
> listeners to an IObservableList.
>
> The only possible solution I can think of is that EMF-Databinding (4CDO)
> has a mode where it internally holds a copy of the original observed
> list to look up the correct objects and create the diff appropriately in
> case of remote change notifications.
>
> Tom
>
> Am 28.01.10 14:28, schrieb Eike Stepper:
>
>> Hi Tom,
>>
>> It would probably mean non-standard processing from a databinding point
>> of view, but wouldn't it basically be easy to scan the affected lists
>> and just remove all CDOObjects with a state INVALID?
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>> Tom Schindl schrieb:
>>
>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>
>>>
>>>> Tom Schindl schrieb:
>>>>
>>>>
>>>>> [...]
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> The reason was/is that the old value is usually rarely used and very
>>>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>>>> original CommitNotificationRequest). After the original notification it
>>>>>> would be impossible to lazily request it from the server if audfiting is
>>>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>>>> change subscription options so that there is a third option beside
>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>>>> we even consider this discussion I'd like to understand what exactly the
>>>>>> old values are used for by data binding.
>>>>>>
>>>>>>
>>>>>>
>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>>>> in an ObservableList of Objects and adds/
>>>>>
>>>>>
>>>> Added objects are delivered by CDO.
>>>>
>>>>
>>>>
>>>>> removes them from a JFace-Viewer.
>>>>>
>>>>>
>>>>>
>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>> delivered by CDO.
>>>>
>>>> Please notice that we're talking about *remote* detach here. A remote
>>>> client has removed an object (or many) and committed that change. The
>>>> particular objects are definitely and irreversibly "gone". They can not
>>>> be meaningfully resurrected. The only option for any other client in the
>>>> network is to release any hold of pointers to their stale copies.
>>>>
>>>>
>>>>
>>> No because the viewer can be reorder the entries based upon Sorters,
>>> Filters, ... .
>>>
>>>
>>>
>>>>> The only other option would be for the JFace-Databinding to refresh the
>>>>> complete viewers contents which is would decrease performance incredible.
>>>>>
>>>>> How would you implement an Table/List-UI which updates itself on changes
>>>>> of a List?
>>>>>
>>>>>
>>>>>
>>>> I suspect that the "UI part" still has a complete old list where the
>>>> detached object must just be removed (removal index should be
>>>> sufficient). Right?
>>>>
>>>>
>>>>
>>> No because if filters are applied to the viewer they are not part of it
>>> any more and an index is not enough because when a ViewerSorter is
>>> applied the list index != table-row-index (hence the viewer doesn't has
>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>
>>>
>>>
>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>> API-contract of Eclipse-Databinding.
>>>>>
>>>>> Probably we should discuss with upstream if they have an API contract
>>>>> for a modification whose content couldn't be identified.
>>>>>
>>>>> What I don't completely understand is that the object removed in this
>>>>> case must be deleted from the local store/list as well (at least in the
>>>>> use case we see here it must have been on the client).
>>>>>
>>>>>
>>>>>
>>>> CDO automatically removes objects that were detached remotely from the
>>>> view cache so that they can no longer be retrieved from it. But if the
>>>> application or a higher-level framework like databinding is still
>>>> holding pointers (strong Java references) to any of these objects
>>>>
>>>>
>>> Well in this case it *could* be that the viewer holds a strong
>>> references (if the element is not filtered out). DB itself is not
>>> holding any pointers but it simply acts as an observe or the underlying
>>> data structure.
>>>
>>> Tom
>>>
>>>
>
>
|
|
|
| Re: [CDO databinding] [message #510800 is a reply to message #510754] |
Thu, 28 January 2010 06:52   |
Eclipse User |
|
|
|
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
>>>>
>>>>
>>>>
>>
>>
|
|
|
| Re: [CDO databinding] [message #510813 is a reply to message #510800] |
Thu, 28 January 2010 12:01   |
Eclipse User |
|
|
|
Ed Merks schrieb:
> Eike,
>
> Yes, I imagine it will happen for any multi-valued feature, including
> EAttributes. It seems likely that in all these cases, the UI itself
> (the view) is still holding onto such old value, e.g., as data in a
> TreeItem, while the control has no record of it.
Yes, that's what I meant. Either it holds onto these objects, or
explicit action is not necessary anyway.
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
>
> Eike Stepper wrote:
>> Hi Tom,
>>
>> I start to understand the "influences" although I don't have a solution
>> yet. Another thing I just realized is, that we (I at least) so far
>> talked about *detached* objects, i.e. elements of many-valued
>> *containment* features. I suspect the same problem occurs with removals
>> from cross references.
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>> Tom Schindl schrieb:
>>
>>> Well the one that is in charge of this is list is out-of-scope for
>>> EMF-Databinding because the only thing it knows is that someone is
>>> observeing it and it informs this observe through a change-event (which
>>> holds the missleading diff)
>>>
>>> The only one who could do this scan in the case is JFace-Databinding
>>> which naturally has no idea about CDO, EMF, ... (in general about the
>>> domain technology) because from its point of view it only attaches
>>> listeners to an IObservableList.
>>>
>>> The only possible solution I can think of is that EMF-Databinding
>>> (4CDO)
>>> has a mode where it internally holds a copy of the original observed
>>> list to look up the correct objects and create the diff
>>> appropriately in
>>> case of remote change notifications.
>>>
>>> Tom
>>>
>>> Am 28.01.10 14:28, schrieb Eike Stepper:
>>>
>>>> Hi Tom,
>>>>
>>>> It would probably mean non-standard processing from a databinding
>>>> point
>>>> of view, but wouldn't it basically be easy to scan the affected lists
>>>> and just remove all CDOObjects with a state INVALID?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>
>>>> Tom Schindl schrieb:
>>>>
>>>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>>>
>>>>>> Tom Schindl schrieb:
>>>>>>
>>>>>>> [...]
>>>>>>>
>>>>>>>
>>>>>>>> The reason was/is that the old value is usually rarely used and
>>>>>>>> very
>>>>>>>> expensive to determine and transfer by CDO in advance (i.e.
>>>>>>>> with the
>>>>>>>> original CommitNotificationRequest). After the original
>>>>>>>> notification it
>>>>>>>> would be impossible to lazily request it from the server if
>>>>>>>> audfiting is
>>>>>>>> not enabled in the repository. We *could* discuss an
>>>>>>>> enhancement in the
>>>>>>>> change subscription options so that there is a third option beside
>>>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>>>> (needed per object?, etc...) and quite some effort. to
>>>>>>>> implement. Before
>>>>>>>> we even consider this discussion I'd like to understand what
>>>>>>>> exactly the
>>>>>>>> old values are used for by data binding.
>>>>>>>>
>>>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to
>>>>>>> changes
>>>>>>> in an ObservableList of Objects and adds/
>>>>>>>
>>>>>> Added objects are delivered by CDO.
>>>>>>
>>>>>>
>>>>>>> removes them from a JFace-Viewer.
>>>>>>>
>>>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>>>> delivered by CDO.
>>>>>>
>>>>>> Please notice that we're talking about *remote* detach here. A
>>>>>> remote
>>>>>> client has removed an object (or many) and committed that change.
>>>>>> The
>>>>>> particular objects are definitely and irreversibly "gone". They
>>>>>> can not
>>>>>> be meaningfully resurrected. The only option for any other client
>>>>>> in the
>>>>>> network is to release any hold of pointers to their stale copies.
>>>>>>
>>>>>>
>>>>> No because the viewer can be reorder the entries based upon Sorters,
>>>>> Filters, ... .
>>>>>
>>>>>
>>>>>>> The only other option would be for the JFace-Databinding to
>>>>>>> refresh the
>>>>>>> complete viewers contents which is would decrease performance
>>>>>>> incredible.
>>>>>>>
>>>>>>> How would you implement an Table/List-UI which updates itself on
>>>>>>> changes
>>>>>>> of a List?
>>>>>>>
>>>>>> I suspect that the "UI part" still has a complete old list where the
>>>>>> detached object must just be removed (removal index should be
>>>>>> sufficient). Right?
>>>>>>
>>>>>>
>>>>> No because if filters are applied to the viewer they are not part
>>>>> of it
>>>>> any more and an index is not enough because when a ViewerSorter is
>>>>> applied the list index != table-row-index (hence the viewer
>>>>> doesn't has
>>>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>>>
>>>>>
>>>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a
>>>>>>> special
>>>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>>>> API-contract of Eclipse-Databinding.
>>>>>>>
>>>>>>> Probably we should discuss with upstream if they have an API
>>>>>>> contract
>>>>>>> for a modification whose content couldn't be identified.
>>>>>>>
>>>>>>> What I don't completely understand is that the object removed in
>>>>>>> this
>>>>>>> case must be deleted from the local store/list as well (at least
>>>>>>> in the
>>>>>>> use case we see here it must have been on the client).
>>>>>>>
>>>>>> CDO automatically removes objects that were detached remotely
>>>>>> from the
>>>>>> view cache so that they can no longer be retrieved from it. But
>>>>>> if the
>>>>>> application or a higher-level framework like databinding is still
>>>>>> holding pointers (strong Java references) to any of these objects
>>>>>>
>>>>> Well in this case it *could* be that the viewer holds a strong
>>>>> references (if the element is not filtered out). DB itself is not
>>>>> holding any pointers but it simply acts as an observe or the
>>>>> underlying
>>>>> data structure.
>>>>>
>>>>> Tom
>>>>>
>>>
|
|
|
| Re: [CDO databinding] [message #510874 is a reply to message #510385] |
Thu, 28 January 2010 17:30   |
Eclipse User |
|
|
|
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] |
Thu, 28 January 2010 23:52   |
Eclipse User |
|
|
|
Hi Boris,
Thanks for the info ;-)
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Boris Bokowski schrieb:
> The following change in TableViewerUpdater could help, but only if the
> TableViewer has no filter or sorter (if it has, the position information
> cannot be used):
> public void remove(Object element, int position) {
>
> if (element != null) {
>
> viewer.remove(element);
>
> } else if (viewer.getComparator() == null &&
> viewer.getFilters.length==0) {
>
> viewer.remove(viewer.getElementAt(position));
>
> } else {
>
> throw new IllegalStateException("some useful message here");
>
> }
>
> }
>
>
>
> Boris
>
>
> "Thomas Kowatsch" <Thomas.Kowatsch@ruag.com> wrote in message
> news:hjpaqo$e12$1@build.eclipse.org...
>
>> Hi,
>>
>> I'm using EMF, CDO and databinding. I have a master detail scenario with a
>> viewer and a detail part. I just was testing what happens when I have
>> opened the application twice to see how the notification and update runs.
>>
>> Now I ran into the problem, that when I delete an entry in Appl1, it
>> crashes in Appl2 when the viewer is refreshed from the
>> ObservableListContentProvider. Here the stack trace:
>>
>>
>> org.eclipse.core.runtime.AssertionFailedException: null argument:
>> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
>> at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:73)
>> at
>> org.eclipse.jface.viewers.StructuredViewer.assertElementsNot Null(StructuredViewer.java:595)
>> at org.eclipse.jface.viewers.TableViewer.remove(TableViewer.jav a:379)
>> at
>> org.eclipse.jface.viewers.AbstractTableViewer.remove(Abstrac tTableViewer.java:856)
>> at
>> org.eclipse.jface.internal.databinding.viewers.TableViewerUp dater.remove(TableViewerUpdater.java:36)
>> at
>> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$2.handleRemove(ObservableListContentProvider.java:12 4)
>> at
>> org.eclipse.core.databinding.observable.list.ListDiff.accept (ListDiff.java:137)
>> at
>> org.eclipse.jface.databinding.viewers.ObservableListContentP rovider$Impl.handleListChange(ObservableListContentProvider. java:118)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.fireListChange(DecoratingObservableList.java:59)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList.handleListChange(DecoratingObservableList.java:97)
>> at
>> org.eclipse.core.databinding.observable.list.DecoratingObser vableList$1.handleListChange(DecoratingObservableList.java:7 1)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.list.ObservableList. fireListChange(ObservableList.java:73)
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList.access$1(DetailObservableList.java:1)
>> at
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableList$1.handleListChange(DetailObservableLi st.java:48)
>> at
>> org.eclipse.core.databinding.observable.list.ListChangeEvent .dispatch(ListChangeEvent.java:61)
>> at
>> org.eclipse.core.databinding.observable.ChangeManager.fireEv ent(ChangeManager.java:119)
>> at
>> org.eclipse.core.databinding.observable.ChangeSupport.fireEv ent(ChangeSupport.java:39)
>> at
>> org.eclipse.core.databinding.observable.list.AbstractObserva bleList.fireListChange(AbstractObservableList.java:114)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.notifyIfChanged(SimplePropertyObservabl eList.java:650)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList.access$3(SimplePropertyObservableList.j ava:642)
>> at
>> org.eclipse.core.internal.databinding.property.list.SimplePr opertyObservableList$2.run(SimplePropertyObservableList.java :78)
>> at org.eclipse.core.databinding.observable.Realm$1.run(Realm.ja va:148)
>> at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
>> at org.eclipse.core.databinding.observable.Realm.safeRun(Realm. java:152)
>> at
>> org.eclipse.jface.databinding.swt.SWTObservables$DisplayReal m.access$0(SWTObservables.java:1)
>> at
>> org.eclipse.jface.databinding.swt.SWTObservables$1.run(SWTOb servables.java:502)
>> at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:3 5)
>> at
>> org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchr onizer.java:134)
>> at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.jav a:3855)
>> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :3476)
>> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:2405)
>> ...
>>
>> So it seems that a "null" object is delivered to the viewer. I tried to
>> track it down further and ended up in
>> EMFListPropertyListener#notifyChanged(Notification). In the switch at case
>> "Notification.REMOVE", a list diff is created with
>> Diffs.createListDiff(Diffs.createListDiffEntry(msg.getPositi on(), false,
>> msg.getOldValue())). Now I guess the problem is that msg.getOldValue()
>> returns null!
>>
>> I checked that also in Appl1 (in the same CDOView that the element is
>> deleted) and saw that msg.getOldValue() returns the deleted object.
>>
>> Is this actually a bug? If not then IMHO CDO and databinding is not usable
>> as is.
>>
>> Cheers.
>> --Thomas
>>
>
>
>
|
|
|
| Re: [CDO databinding] [message #511595 is a reply to message #510754] |
Tue, 02 February 2010 03:30   |
Eclipse User |
|
|
|
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 03:47   |
Eclipse User |
|
|
|
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] |
Mon, 01 February 2010 23:28   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------010607010609030101060000
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit
Tom Schindl schrieb:
> Hi Eike,
>
> I rethought the issue and if I get this right the problem is when the
> instance is *NOT* the local cache else you would have been able to look
> it up from there?
>
I verified that the instance will not be in the cache:
| *private static class *DetachRemoteTransition *implements *ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
{
*static *DetachRemoteTransition INSTANCE = *new *DetachRemoteTransition();
*public **void *execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
{
InternalCDOView view = object.cdoView();
_view.deregisterObject(object);_
_object.cdoInternalSetState(CDOState.INVALID);_
object.cdoInternalPostDetach(*true*);
}
}|
Note that, no matter through what pointer path an INVALID instance is
accessed, the instance will throw IllegalStateException from most of its
methods.
> Would it be possible for CDO to send a PRE-Remove Notification so that
> clients who need a reference to the object can "prefetch" it so that it
> gets part of the cache and your change notification can look it up from
> there and provide the instance?
>
That doesn't sound like a reasonable option. A notification like that
would really have to be an "agent-like" *request* rather than a one-way
notification. It would suspend the originating commit operation on the
server until all clients have signalled (responded) that they have done
what they wanted to do. Otherwise it would be very unlikely that they
get what they want to get (the old object data) because the commit
operation would already have overwritten this data. Synchronous requests
to all client from within the server commit operation are just not
acceptable.
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
> I'm going to bug Boris and Matt in the meantime to get their statement
> on the change-notification in case the removed instance can't be provided.
>
> Tom
>
> Am 28.01.10 15:39, schrieb Eike Stepper:
>
>> Hi Tom,
>>
>> I start to understand the "influences" although I don't have a solution
>> yet. Another thing I just realized is, that we (I at least) so far
>> talked about *detached* objects, i.e. elements of many-valued
>> *containment* features. I suspect the same problem occurs with removals
>> from cross references.
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>> Tom Schindl schrieb:
>>
>>> Well the one that is in charge of this is list is out-of-scope for
>>> EMF-Databinding because the only thing it knows is that someone is
>>> observeing it and it informs this observe through a change-event (which
>>> holds the missleading diff)
>>>
>>> The only one who could do this scan in the case is JFace-Databinding
>>> which naturally has no idea about CDO, EMF, ... (in general about the
>>> domain technology) because from its point of view it only attaches
>>> listeners to an IObservableList.
>>>
>>> The only possible solution I can think of is that EMF-Databinding (4CDO)
>>> has a mode where it internally holds a copy of the original observed
>>> list to look up the correct objects and create the diff appropriately in
>>> case of remote change notifications.
>>>
>>> Tom
>>>
>>> Am 28.01.10 14:28, schrieb Eike Stepper:
>>>
>>>
>>>> Hi Tom,
>>>>
>>>> It would probably mean non-standard processing from a databinding point
>>>> of view, but wouldn't it basically be easy to scan the affected lists
>>>> and just remove all CDOObjects with a state INVALID?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>
>>>> Tom Schindl schrieb:
>>>>
>>>>
>>>>> Am 28.01.10 12:53, schrieb Eike Stepper:
>>>>>
>>>>>
>>>>>
>>>>>> Tom Schindl schrieb:
>>>>>>
>>>>>>
>>>>>>
>>>>>>> [...]
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> The reason was/is that the old value is usually rarely used and very
>>>>>>>> expensive to determine and transfer by CDO in advance (i.e. with the
>>>>>>>> original CommitNotificationRequest). After the original notification it
>>>>>>>> would be impossible to lazily request it from the server if audfiting is
>>>>>>>> not enabled in the repository. We *could* discuss an enhancement in the
>>>>>>>> change subscription options so that there is a third option beside
>>>>>>>> ON/OFF: ON_WITH_OLD_VALUES. This would require a sensible analysis
>>>>>>>> (needed per object?, etc...) and quite some effort. to implement. Before
>>>>>>>> we even consider this discussion I'd like to understand what exactly the
>>>>>>>> old values are used for by data binding.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>> Eclipse-Databinding or in this case JFace-Databinding listens to changes
>>>>>>> in an ObservableList of Objects and adds/
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> Added objects are delivered by CDO.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> removes them from a JFace-Viewer.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> Only the index of the removed objects is needed for that, and AFAIK
>>>>>> delivered by CDO.
>>>>>>
>>>>>> Please notice that we're talking about *remote* detach here. A remote
>>>>>> client has removed an object (or many) and committed that change. The
>>>>>> particular objects are definitely and irreversibly "gone". They can not
>>>>>> be meaningfully resurrected. The only option for any other client in the
>>>>>> network is to release any hold of pointers to their stale copies.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> No because the viewer can be reorder the entries based upon Sorters,
>>>>> Filters, ... .
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>> The only other option would be for the JFace-Databinding to refresh the
>>>>>>> complete viewers contents which is would decrease performance incredible.
>>>>>>>
>>>>>>> How would you implement an Table/List-UI which updates itself on changes
>>>>>>> of a List?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> I suspect that the "UI part" still has a complete old list where the
>>>>>> detached object must just be removed (removal index should be
>>>>>> sufficient). Right?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> No because if filters are applied to the viewer they are not part of it
>>>>> any more and an index is not enough because when a ViewerSorter is
>>>>> applied the list index != table-row-index (hence the viewer doesn't has
>>>>> TableViewer#remove(int) but only TableViewer#remove(Object)).
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>> We could ask the JFace-Viewer-Databinding maintainers to add a special
>>>>>>> case in their code which leads to a complete refresh if the Diff is
>>>>>>> empty or holds an null-value but I guess CDOs behaviour breaks the
>>>>>>> API-contract of Eclipse-Databinding.
>>>>>>>
>>>>>>> Probably we should discuss with upstream if they have an API contract
>>>>>>> for a modification whose content couldn't be identified.
>>>>>>>
>>>>>>> What I don't completely understand is that the object removed in this
>>>>>>> case must be deleted from the local store/list as well (at least in the
>>>>>>> use case we see here it must have been on the client).
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> CDO automatically removes objects that were detached remotely from the
>>>>>> view cache so that they can no longer be retrieved from it. But if the
>>>>>> application or a higher-level framework like databinding is still
>>>>>> holding pointers (strong Java references) to any of these objects
>>>>>>
>>>>>>
>>>>>>
>>>>> Well in this case it *could* be that the viewer holds a strong
>>>>> references (if the element is not filtered out). DB itself is not
>>>>> holding any pointers but it simply acts as an observe or the underlying
>>>>> data structure.
>>>>>
>>>>> Tom
>>>>>
>>>>>
>>>>>
>>>
>>>
>
>
--------------010607010609030101060000
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Tom Schindl schrieb:
<blockquote cite="mid:hk8nri$3ip$1@build.eclipse.org" type="cite">
<pre wrap="">Hi Eike,
I rethought the issue and if I get this right the problem is when the
instance is *NOT* the local cache else you would have been able to look
it up from there?
</pre>
</blockquote>
I verified that the instance will not be in the cache:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#ffffff">
|
|
|
| Re: [CDO databinding] [message #515416 is a reply to message #510385] |
Thu, 18 February 2010 07: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 07:46   |
Eclipse User |
|
|
|
Hi Thomas,
Okay, there seem to be these two, different issues:
1) No old value for REMOVE and REMOVE_MANY
2) Objects in state INVALID after remote deletion
I must admit that, from a distance, I can not understand all the
concrete details about databinding. I could offer to play with a working
example if you provide that. I suggest that we talk via Skype about that.
I could imagine that I can solve 1) somehow in CDO, e.g. optionally
broadcast the old values and feed the adapters with them.
But I don't see so much how 2) can be solved generically. In a
distributed concurrent environment soe things *are* just different.
Maybe with more knowledge about databinding I get a new idea...
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
> Hi.
>
> Is there anybody out there who is still working on a solution of this
> problem?
>
> Or at least thinking about a solution?
>
> This problem is essential to our project and our project will fail, if
> there is none, as we relied on the fact that databinding is working
> together with CDO.
>
> IMO it works excellent as long as you are working with one CDOView or
> CDOTransaction. As soon as you have a remote CDVOView the whole thing
> is behaving very bad when you e.g. remove an object.
>
> One reason is that CDODeltaNotification is unable to deliver all
> needed data for databinding, i.e. on remove, the oldValue is just
> missing.
>
> Another reason is that when accessing an INVALID CDOObject, an
> exception is thrown.
>
> I tried to work araound those problems a bit, just to get it running.
> But when I solved one problem just one or more other come up.
>
> What I have done so far:
>
> - first I tried to solve the issue that ViewerUpdater will fail when
> remove is called with a null (that is now fixed) or an empty
> collection element. I just wrote a custom ViewerUpdater that is passed
> to ObservableListContentProvider. I just did a refresh() in any case
> the needed information is missing. In my example here that would be if
> remove(Object element, int position) is called with an empty list, I
> do a refresh().
>
> - that worked quite ok, but then I had the next problem. We are having
> a master-detail situation and I followed the instructions from Tom's
> blog about EMF databinding. This uses a WriteableValue for the master
> observable. Everything worked quite ok, until the remote viewer (the
> viewer in the application that gets the remote remove notification)
> has currently selected the remotely removed element. In this case the
> WritableValue will get a value change because the selection of the
> viewer changes (the element was removed). Now a diff is created with
> the old, INVALID CDOObject as oldValue. Whenever this oldValue is
> accessed (or lets say an attribute of the oldValue) it will fail with
> the exception. So I though I overwrite two methods of WritableValue to
> solve this issue, i.e. fireValueChange(ValueDiff) and goGetValue(). In
> fireValueChange() I check if the oldValue in the passed diff is an
> invalid object and if it is, I replace it with null and carry on with
> super.fireValueChange(). in doGetValue() I check if the cached value
> is an invalid object and return null in case. This solved the problems
> so far for all clients using the WritableValue or have a
> ValueChangedListener attached.
>
> - that is all ok and handable when it is in your program code. But if
> you use framework code you cannot overwrite this. The
> ....observeDetail(master) methods create DetailObservableValues that
> hold the master value as currentOuterValue. If this object is an
> INVALID CDOObject, then it fails when the master changes as in the
> outerChangeListener a doGetValue() is done at the beginning which
> tries to read an EAttribute from the INVALID object. I guess this
> happens throughout all databinding master-detail objects. For example,
> the label provider uses an attribute map to observe the attributes
> that are displayed by the LabelProvider, these are in generell
> DetailObservableValues which might access the INVALID object's
> attributes.
>
> At this point I decided to write this post, as I'm quite stuck and
> don't know how to proceed. I have no idea anymore how to solve that
> myself...
>
> Any advices?
>
> Cheers.
> --Thomas
|
|
|
| Re: [CDO databinding] [message #515425 is a reply to message #515417] |
Thu, 18 February 2010 08: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 08:16   |
Eclipse User |
|
|
|
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 01:04   |
Eclipse User |
|
|
|
Am 18.02.2010 19:09, schrieb Tom Schindl:
> Hi,
>
> Ideally we get some JUnit-Test-Cases so that Eike and I can get together
> and find a solution.
>
Yes, that should be the next step.
> Probably we even need upstream support. Just an idea would it be
> possible to configure CDO so that it returns a NULL instead of throwing
> an exception when someone wants to access an attribute of an INVALID-Object?
>
That has been discussed earlier but I'm not a fan of this "hack", as it
leaves a client with in a state that just is invalid with respect to the
repository state and then there's no way of even recognizing this.
> Ideally Eclipse-Databinding would provide API to configure error
> handling for such cases. The main problem is that M6 is API-Freeze and
> the chance to get new API in at this stage is quite hard (probably
> impossible).
>
We can only try. Try quickly ;-)
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
> Tom
>
> Am 18.02.10 18:59, schrieb Thomas Kowatsch:
>
>> Hi Eike.
>> Many thanks for the quick answer.
>> Comments below.
>> Cheers.
>> --Thomas
>>
>> Eike Stepper schrieb:
>>
>>> Hi Thomas,
>>>
>>> Okay, there seem to be these two, different issues:
>>>
>>> 1) No old value for REMOVE and REMOVE_MANY
>>> 2) Objects in state INVALID after remote deletion
>>>
>>> I must admit that, from a distance, I can not understand all the
>>> concrete details about databinding. I could offer to play with a
>>> working example if you provide that. I suggest that we talk via Skype
>>> about that.
>>>
>>> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
>>> broadcast the old values and feed the adapters with them.
>>>
>> Ok. But this problem is not so bad, as it can be solved with a custom
>> ViewerUpdater as I described below. But maybe thats also an option which
>> might be needed by others in CDO...
>>
>>> But I don't see so much how 2) can be solved generically. In a
>>> distributed concurrent environment soe things *are* just different.
>>> Maybe with more knowledge about databinding I get a new idea...
>>>
>> Ideas, that was one of the reasons for my latest post. At the moment I
>> can only think about a special CDO adapted databinding package.... But
>> this will be hard and great effort, I guess...
>>
>>> Cheers
>>> /Eike
>>>
>>> ----
>>> http://thegordian.blogspot.com
>>> http://twitter.com/eikestepper
>>>
>>>
>>>
>>>
>>> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>>>
>>>> Hi.
>>>>
>>>> Is there anybody out there who is still working on a solution of this
>>>> problem?
>>>>
>>>> Or at least thinking about a solution?
>>>>
>>>> This problem is essential to our project and our project will fail,
>>>> if there is none, as we relied on the fact that databinding is
>>>> working together with CDO.
>>>>
>>>> IMO it works excellent as long as you are working with one CDOView or
>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>>>> is behaving very bad when you e.g. remove an object.
>>>>
>>>> One reason is that CDODeltaNotification is unable to deliver all
>>>> needed data for databinding, i.e. on remove, the oldValue is just
>>>> missing.
>>>>
>>>> Another reason is that when accessing an INVALID CDOObject, an
>>>> exception is thrown.
>>>>
>>>> I tried to work araound those problems a bit, just to get it running.
>>>> But when I solved one problem just one or more other come up.
>>>>
>>>> What I have done so far:
>>>>
>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>> remove is called with a null (that is now fixed) or an empty
>>>> collection element. I just wrote a custom ViewerUpdater that is
>>>> passed to ObservableListContentProvider. I just did a refresh() in
>>>> any case the needed information is missing. In my example here that
>>>> would be if remove(Object element, int position) is called with an
>>>> empty list, I do a refresh().
>>>>
>>>> - that worked quite ok, but then I had the next problem. We are
>>>> having a master-detail situation and I followed the instructions from
>>>> Tom's blog about EMF databinding. This uses a WriteableValue for the
>>>> master observable. Everything worked quite ok, until the remote
>>>> viewer (the viewer in the application that gets the remote remove
>>>> notification) has currently selected the remotely removed element. In
>>>> this case the WritableValue will get a value change because the
>>>> selection of the viewer changes (the element was removed). Now a diff
>>>> is created with the old, INVALID CDOObject as oldValue. Whenever this
>>>> oldValue is accessed (or lets say an attribute of the oldValue) it
>>>> will fail with the exception. So I though I overwrite two methods of
>>>> WritableValue to solve this issue, i.e. fireValueChange(ValueDiff)
>>>> and goGetValue(). In fireValueChange() I check if the oldValue in the
>>>> passed diff is an invalid object and if it is, I replace it with null
>>>> and carry on with super.fireValueChange(). in doGetValue() I check if
>>>> the cached value is an invalid object and return null in case. This
>>>> solved the problems so far for all clients using the WritableValue or
>>>> have a ValueChangedListener attached.
>>>>
>>>> - that is all ok and handable when it is in your program code. But if
>>>> you use framework code you cannot overwrite this. The
>>>> ....observeDetail(master) methods create DetailObservableValues that
>>>> hold the master value as currentOuterValue. If this object is an
>>>> INVALID CDOObject, then it fails when the master changes as in the
>>>> outerChangeListener a doGetValue() is done at the beginning which
>>>> tries to read an EAttribute from the INVALID object. I guess this
>>>> happens throughout all databinding master-detail objects. For
>>>> example, the label provider uses an attribute map to observe the
>>>> attributes that are displayed by the LabelProvider, these are in
>>>> generell DetailObservableValues which might access the INVALID
>>>> object's attributes.
>>>>
>>>> At this point I decided to write this post, as I'm quite stuck and
>>>> don't know how to proceed. I have no idea anymore how to solve that
>>>> myself...
>>>>
>>>> Any advices?
>>>>
>>>> Cheers.
>>>> --Thomas
>>>>
>
|
|
|
| Re: [CDO databinding] [message #515523 is a reply to message #515426] |
Thu, 18 February 2010 23: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] |
Thu, 18 February 2010 23:26   |
Eclipse User |
|
|
|
Am 19.02.2010 10:03, schrieb Thomas Kowatsch:
> Hi Tom.
> Comments below...
> Cheers.
> --Thomas
>
> Tom Schindl schrieb:
>> Hi,
>>
>> Ideally we get some JUnit-Test-Cases so that Eike and I can get together
>> and find a solution.
> I will do that on Monday with a colleague. It is quite a bit of work
> though, as the situation is a bit complicated (need two transactions,
> master-detail scenario, no UI, ...). Is there any test for an EMF/CDO
> Databinding master-detail scenario which could be taken as base?
Not that I know of. Tom?
Cheers
/Eike
----
http://thegordian.blogspot.com
http://twitter.com/eikestepper
>>
>> Probably we even need upstream support. Just an idea would it be
>> possible to configure CDO so that it returns a NULL instead of throwing
>> an exception when someone wants to access an attribute of an
>> INVALID-Object?
>>
>> Ideally Eclipse-Databinding would provide API to configure error
>> handling for such cases. The main problem is that M6 is API-Freeze and
>> the chance to get new API in at this stage is quite hard (probably
>> impossible).
>>
>> Tom
>>
>> Am 18.02.10 18:59, schrieb Thomas Kowatsch:
>>> Hi Eike.
>>> Many thanks for the quick answer.
>>> Comments below.
>>> Cheers.
>>> --Thomas
>>>
>>> Eike Stepper schrieb:
>>>> Hi Thomas,
>>>>
>>>> Okay, there seem to be these two, different issues:
>>>>
>>>> 1) No old value for REMOVE and REMOVE_MANY
>>>> 2) Objects in state INVALID after remote deletion
>>>>
>>>> I must admit that, from a distance, I can not understand all the
>>>> concrete details about databinding. I could offer to play with a
>>>> working example if you provide that. I suggest that we talk via Skype
>>>> about that.
>>>>
>>>> I could imagine that I can solve 1) somehow in CDO, e.g. optionally
>>>> broadcast the old values and feed the adapters with them.
>>> Ok. But this problem is not so bad, as it can be solved with a custom
>>> ViewerUpdater as I described below. But maybe thats also an option
>>> which
>>> might be needed by others in CDO...
>>>> But I don't see so much how 2) can be solved generically. In a
>>>> distributed concurrent environment soe things *are* just different.
>>>> Maybe with more knowledge about databinding I get a new idea...
>>> Ideas, that was one of the reasons for my latest post. At the moment I
>>> can only think about a special CDO adapted databinding package.... But
>>> this will be hard and great effort, I guess...
>>>> Cheers
>>>> /Eike
>>>>
>>>> ----
>>>> http://thegordian.blogspot.com
>>>> http://twitter.com/eikestepper
>>>>
>>>>
>>>>
>>>>
>>>> Am 18.02.2010 18:13, schrieb Thomas Kowatsch:
>>>>> Hi.
>>>>>
>>>>> Is there anybody out there who is still working on a solution of this
>>>>> problem?
>>>>>
>>>>> Or at least thinking about a solution?
>>>>>
>>>>> This problem is essential to our project and our project will fail,
>>>>> if there is none, as we relied on the fact that databinding is
>>>>> working together with CDO.
>>>>>
>>>>> IMO it works excellent as long as you are working with one CDOView or
>>>>> CDOTransaction. As soon as you have a remote CDVOView the whole thing
>>>>> is behaving very bad when you e.g. remove an object.
>>>>>
>>>>> One reason is that CDODeltaNotification is unable to deliver all
>>>>> needed data for databinding, i.e. on remove, the oldValue is just
>>>>> missing.
>>>>>
>>>>> Another reason is that when accessing an INVALID CDOObject, an
>>>>> exception is thrown.
>>>>>
>>>>> I tried to work araound those problems a bit, just to get it running.
>>>>> But when I solved one problem just one or more other come up.
>>>>>
>>>>> What I have done so far:
>>>>>
>>>>> - first I tried to solve the issue that ViewerUpdater will fail when
>>>>> remove is called with a null (that is now fixed) or an empty
>>>>> collection element. I just wrote a custom ViewerUpdater that is
>>>>> passed to ObservableListContentProvider. I just did a refresh() in
>>>>> any case the needed information is missing. In my example here that
>>>>> would be if remove(Object element, int position) is called with an
>>>>> empty list, I do a refresh().
>>>>>
>>>>> - that worked quite ok, but then I had the next problem. We are
>>>>> having a master-detail situation and I followed the instructions from
>>>>> Tom's blog about EMF databinding. This uses a WriteableValue for the
>>>>> master observable. Everything worked quite ok, until the remote
>>>>> viewer (the viewer in the application that gets the remote remove
>>>>> notification) has currently selected the remotely removed element. In
>>>>> this case the WritableValue will get a value change because the
>>>>> selection of the viewer changes (the element was removed). Now a diff
>>>>> is created with the old, INVALID CDOObject as oldValue. Whenever this
>>>>> oldValue is accessed (or lets say an attribute of the oldValue) it
>>>>> will fail with the exception. So I though I overwrite two methods of
>>>>> WritableValue to solve this issue, i.e. fireValueChange(ValueDiff)
>>>>> and goGetValue(). In fireValueChange() I check if the oldValue in the
>>>>> passed diff is an invalid object and if it is, I replace it with null
>>>>> and carry on with super.fireValueChange(). in doGetValue() I check if
>>>>> the cached value is an invalid object and return null in case. This
>>>>> solved the problems so far for all clients using the WritableValue or
>>>>> have a ValueChangedListener attached.
>>>>>
>>>>> - that is all ok and handable when it is in your program code. But if
>>>>> you use framework code you cannot overwrite this. The
>>>>> ....observeDetail(master) methods create DetailObservableValues that
>>>>> hold the master value as currentOuterValue. If this object is an
>>>>> INVALID CDOObject, then it fails when the master changes as in the
>>>>> outerChangeListener a doGetValue() is done at the beginning which
>>>>> tries to read an EAttribute from the INVALID object. I guess this
>>>>> happens throughout all databinding master-detail objects. For
>>>>> example, the label provider uses an attribute map to observe the
>>>>> attributes that are displayed by the LabelProvider, these are in
>>>>> generell DetailObservableValues which might access the INVALID
>>>>> object's attributes.
>>>>>
>>>>> At this point I decided to write this post, as I'm quite stuck and
>>>>> don't know how to proceed. I have no idea anymore how to solve that
>>>>> myself...
>>>>>
>>>>> Any advices?
>>>>>
>>>>> Cheers.
>>>>> --Thomas
>>
|
|
|
| Re: [CDO databinding] [message #515539 is a reply to message #515524] |
Fri, 19 February 2010 05:09   |
Eclipse User |
|
|
|
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 #516194 is a reply to message #515416] |
Mon, 22 February 2010 21:22   |
Eclipse User |
|
|
|
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] |
Mon, 22 February 2010 22:34   |
Eclipse User |
|
|
|
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 05:18   |
Eclipse User |
|
|
|
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 18:48   |
Eclipse User |
|
|
|
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 03: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 #526572 is a reply to message #526560] |
Mon, 12 April 2010 06: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 07:51  |
Eclipse User |
|
|
|
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--
|
|
|
Goto Forum:
Current Time: Mon Oct 27 14:05:14 EDT 2025
Powered by FUDForum. Page generated in 0.16313 seconds
|