| [news.eclipse.platform] Re: [Databinding] Problem with MasterDetail and EObjectObservableMap |
Michael,
Comments below.
I still don't see how this generally makes sense. You might have a feature that's multi-valued so you return a list that can be modified. The list might be empty. Then in other cases you return an empty list that can't be modified. I don't see how the downstream code can deal with it sometimes being modifiable and sometimes not.Ed,
sorry, I have been on vacation for a week, but if you don't mind I'd like to continue this discussion a little bit. I've put some specific comments below:
Ed Merks wrote:As I already mentioned in my reply to Boris, I rather think that the base framework "only" handles a special case in Master-Detail scenarios, namely those where the Master list contains only elements of the same type, whereas the usecase described by me is more general. The question is of course if this case can be handled by the framework at all or if customizations are unavoidable.Michael,
Michael Haeberlen wrote:They're kind of annoying confusing things, but necessary to support XML Schema-based models.Ed,
I'm not quite sure I understand. (actually I don't know what a "wildcard feature" is).So, you are saying that the solution I sketched will not work in general?It's not a general change that I would put in the framework no, because there would be cases it disables that would work well today.Would you agree that in my special case I described it does work?I can imagine why you'd want an empty list in specialized cases where you're trying to view objects but not all are uniforming of a type where the feature is applicable.Or do you see problems even there? (however, I don't think this solution makes it worse, logically at least).I'm not sure what would happen if you tried to modify the empty list, but maybe that's not an issue.Or are you saying that I should not use a ComputedList the way I did in order to combine the two lists? (btw., forget the line with the "UnionList" it should have been commented out)No, my comment was purely about what the base framework does, not about how you might specialize it in specific scenarios.
Probably any runtime error will be considered strange, but it can only be check at runtime. We could certainly check for validity at the time the observable is created, so I'd be open to adding such a fail-faster check. But I still don't understand how returning a read-only list is a good thing. E.g., how will the details view indicate that some field is not actually bound to an editable feature? I.e., shouldn't the widget that controls the value be disabled?This is of course my fault and I apologize both for the bad description and for being suggestive of considering the current behavior as a bug, which I don't. To give a concrete example of what I mean, consider the a file system model like the one that you presented in http://ed-merks.blogspot.com/2008/01/creating-children-you-didnt-know.html (ignoring the extensibility features described there) Here a selection in the master can either be a "File" or a "Folder". If I want to present a feature which is only present for "File" in my details part and use EMFEditObservables.observeDetailValue as-is, I get into trouble. And the problem is, that EMFEditObservables.valueFactory assumes that "eStructuralFeature" is a feature of "target" (using the variable names of the implementation), and it even does not check if this is the case (potentially) causing strange runtime errors.I'm not sure the problem was entirely sketched out in a way that I understand it. Whatever makes it work for you is fine. You just talked about opening a bug, and I'm commentingon the fact that I don't see the behavior in the base framework as a bug. The framework is not intended to gracefully support creating no-op/empty observables for features that have no meaning relative to the target object.
The other question is what else could I do in order to fix the problem (and still use (emf-)databinding) ?
Thanks, Michael
Ed Merks wrote:Michael,
This approach would end up not supporting open content features, i.e., features of a document root that are accepted by a wildcard feature of the actual class. I don't think you should be applying it for invalid cases. I believe it fails with an exception right now if you do that, which seems to me the right approach.
Michael Haeberlen wrote:Sorry, the method in EMFEditObservables has to be changed to:
public IObservable createObservable(Object target)
{
if (eStructuralFeature.getEContainingClass().isSuperTypeOf(((EObject) target).eClass()))
{
return observeList(realm, domain, (EObject)target, eStructuralFeature);
}
return new EmptyObservableList(realm, eStructuralFeature);
}
i.e. we must not return null here.
Michael
Michael Haeberlen wrote:Hi,
I am using a org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider as content provider in my master tree view. I use a IObservableFactory which provides a combination of two IObservableList lists like follows:
public IObservable createObservable(Object target) {
final IObservableList list1 = EMFEditObservables.observeList(domain, target, XYZPackage.Literals.TARGET_FEATURE1);
final IObservableList list2 = EMFEditObservables.observeList(domain, target, XYZPackage.Literals.TARGET_FEATURE2);
return new UnionList(new IObservableList[] {categoryList, childList});
return new ComputedList() {
protected List calculate() {
List list = new ArrayList(list1.size()+list2.size());
list.addAll(list1);
list.addAll(list2);
return list;
}
};
}
So now I have objects in my tree which represent different features, and so I have different details pages.
In the details pages, I have code like this:
IObservableValue selection = ViewersObservables.observeSingleSelection(viewer); //viewer is the master view tree viewer
EMFEditObservables.observeDetailList(realm, domain, selection, XYZPackage.Literals.FEATURE_OF_SELECTION));
And here is my problem: EMFEditObservables uses a IObservableFactory which assumes that the target (=selection) is always an EObject having the specified feature:
public IObservable createObservable(Object target)
{
return observeList(realm, domain, (EObject)target, eStructuralFeature);
}
If the above method was changed to the following:
public IObservable createObservable(Object target)
{
if (eStructuralFeature.getEContainingClass().isSuperTypeOf(((EObject)target).eClass()))
{
return observeList(realm, domain, (EObject)target, eStructuralFeature);
}
return null;
}
then my problem is gone.
Before opening a bug I just wanted to ask if this is the right way to solve it or if I should have done something different?
Thanks, Michael