| [news.eclipse.tools.emf] Re: Databinding and EFeatureMap (Re: AdapterFactoryContentProvider and notificat |
Ron,
I see. I've really never tested these things. It certain assumes the domainElements are EObjects obviously....Ed Merks wrote:
Ron,
I think I'd need to see a test case to track what's going wrong and to fix it. I can't quite see how it ended up in map code given you showed observing a list...
Hi, Ed!
I tried to step through the code and this is what happens:
getEditingDomain().getResourceSet().getResources().get(0).getContents().get(0);Library library = (Library)
// A content provider that listens to an IObservableList
ObservableListContentProvider cp = new ObservableListContentProvider();
tableViewer2.setContentProvider(cp);
// Name column
maps = EMFObservables.observeMaps(cp.getKnownElements(), new EStructuralFeature[] {
ExtlibraryPackage.Literals.PERSON__LAST_NAME,
ExtlibraryPackage.Literals.PERSON__FIRST_NAME
});
Two EObjectObservableMaps are created which track cp.getKnownElements() (currently empty) as the set of keys.// Address column
IObservableMap map = EMFObservables.observeMap(cp.getKnownElements(), ExtlibraryPackage.Literals.ADDRESSABLE__ADDRESS);
Same here...
IObservableList list = EMFObservables.observeList(library, ExtlibraryPackage.Literals.LIBRARY__PEOPLE);
tableViewer2.setInput(list);
ObservableListContentProvider tries to populate cp.getKnownElements() set with the entries from library.getPeople(). As these are populated, the EObjectObservableMaps above get notified, and they try to hook themselves into the objects being added.
Normally (when the attribute is an EList containing EObjects) this works fine, but in this case the list contains FeatureMap.Entry objects.. The hook code in EObjectObservableMap assumes EObjects and so a CCE exception occurs.
I could imagine if you hooked up to say the mixed text feature of a complex type you'd have some entries that hold simple values and some that hold EObject...
protected void hookListener(Object domainElement) { ((EObject)domainElement).eAdapters().add(elementListener); }
When I tried to change it to:
protected void hookListener(Object domainElement)
{
if (domainElement instanceof FeatureMap.Entry) {
EObject eo = (EObject) ((FeatureMap.Entry) domainElement).getValue();
eo.eAdapters().add(elementListener);
} else {
((EObject)domainElement).eAdapters().add(elementListener);
}
}
It seems to me that everything should be handled gracefully. But as I said in other notes in the group, I've really tested this stuff very little. I told Boris I wasn't going to check in the map support because I didn't understand how it was used. So he explained it to him and then it made more sense, but that was a few months ago now. If you wanted to send me a zipped up (exported) set of projects I could import to reproduce the problem either in the newsgroup or to merks at ca dot ibm dot com I'd have a look at fixing it in time for next week's build....
it works ok. (I had to change to other methods similarly, too).
I don't know if EObjectObservableMap is really supposed to handle the case of the key being a FeatureMap.Entry, or some unwrapping logic (FeatureMap.Entry#getValue()) needs to be inserted outside... (but where?) :-)
Cheers! Ron