Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » [Databinding] Problem with MasterDetail and EObjectObservableMap
[Databinding] Problem with MasterDetail and EObjectObservableMap [message #328173] Fri, 16 May 2008 10:27 Go to next message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
Hi,

I am using a org.eclipse.jface.databinding.viewers.ObservableListTreeCont entProvider 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328174 is a reply to message #328173] Fri, 16 May 2008 10:55 Go to previous messageGo to next message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
Sorry, the method in EMFEditObservables has to be changed to:

public IObservable createObservable(Object target)
{
if (eStructuralFeature.getEContainingClass().isSuperTypeOf(((EO bject) 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.ObservableListTreeCont entProvider
> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328183 is a reply to message #328174] Fri, 16 May 2008 14:08 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

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(((EO bject)
> 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.ObservableListTreeCont entProvider
>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328186 is a reply to message #328183] Fri, 16 May 2008 14:38 Go to previous messageGo to next message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
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? Would you agree that in my special case I described it does work? Or do
you see problems even there? (however, I don't think this solution makes it worse, logically at least).
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)

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(((EO bject)
>> 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.ObservableListTreeCont entProvider
>>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328188 is a reply to message #328186] Fri, 16 May 2008 14:57 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

Michael Haeberlen wrote:
> Ed,
>
> I'm not quite sure I understand. (actually I don't know what a
> "wildcard feature" is).
They're kind of annoying confusing things, but necessary to support XML
Schema-based models.
> 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.
>
> The other question is what else could I do in order to fix the problem
> (and still use (emf-)databinding) ?
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.
>
> 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(((EO bject)
>>> 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.ObservableListTreeCont entProvider
>>>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328287 is a reply to message #328186] Tue, 20 May 2008 18:08 Go to previous messageGo to next message
Boris Bokowski is currently offline Boris BokowskiFriend
Messages: 272
Registered: July 2009
Senior Member
Michael,

I would be surprised if you could not implement a variant of
EMFEditObservables.observeDetailList that works the way you need it to. The
method observeDetailList is a convenience method for
MasterDetailObservables.detailList(master, listFactory, propertyType); you
should be able to write a list factory that wraps the original one but first
performs whatever checks you need.

Boris

"Michael Haeberlen" <haeber@de.ibm.com> wrote in message
news:g0k68c$8vi$1@build.eclipse.org...
> 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? Would you agree that in my special case I described it
> does work? Or do you see problems even there? (however, I don't think this
> solution makes it worse, logically at least).
> 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)
>
> 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(((EO bject)
>>> 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.ObservableListTreeCont entProvider
>>>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328477 is a reply to message #328287] Mon, 26 May 2008 12:34 Go to previous messageGo to next message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
Boris,

thanks for your hint, in fact, this is exactly what I already did. The point that I was trying to make - and I admit
that this has not been very clear - is that I was hoping that this functionality could - somehow? - be provided by the
framework itself. I still think that the scenario described by me is not a "special" case, I rather tend to claim that
this is the "general" case and the EMFEditObservables "only" handles a "special" case (where all children of the master
list are of the same type).

Michael

Boris Bokowski wrote:
> Michael,
>
> I would be surprised if you could not implement a variant of
> EMFEditObservables.observeDetailList that works the way you need it to. The
> method observeDetailList is a convenience method for
> MasterDetailObservables.detailList(master, listFactory, propertyType); you
> should be able to write a list factory that wraps the original one but first
> performs whatever checks you need.
>
> Boris
>
> "Michael Haeberlen" <haeber@de.ibm.com> wrote in message
> news:g0k68c$8vi$1@build.eclipse.org...
>> 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? Would you agree that in my special case I described it
>> does work? Or do you see problems even there? (however, I don't think this
>> solution makes it worse, logically at least).
>> 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)
>>
>> 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(((EO bject)
>>>> 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.ObservableListTreeCont entProvider
>>>>> 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(((EO bject)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
>
>
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328482 is a reply to message #328188] Mon, 26 May 2008 13:02 Go to previous messageGo to next message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
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:
> Michael,
>
> Michael Haeberlen wrote:
>> Ed,
>>
>> I'm not quite sure I understand. (actually I don't know what a
>> "wildcard feature" is).
> They're kind of annoying confusing things, but necessary to support XML
> Schema-based models.
>> 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.
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.
>>
>> The other question is what else could I do in order to fix the problem
>> (and still use (emf-)databinding) ?
> 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.
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-d idnt-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.

>>
>> 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(((EO bject)
>>>> 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.ObservableListTreeCont entProvider
>>>>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328490 is a reply to message #328482] Mon, 26 May 2008 14:39 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

Comments below.


Michael Haeberlen wrote:
> 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:
>> Michael,
>>
>> Michael Haeberlen wrote:
>>> Ed,
>>>
>>> I'm not quite sure I understand. (actually I don't know what a
>>> "wildcard feature" is).
>> They're kind of annoying confusing things, but necessary to support
>> XML Schema-based models.
>>> 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.
> 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.
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.
>>>
>>> The other question is what else could I do in order to fix the
>>> problem (and still use (emf-)databinding) ?
>> 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.
> 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-d idnt-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.
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?

Again, I've not used the framework for any significant development work
myself, which is why it's marked as provisional API. Hopefully in the
next release I'll have an opportunity for that.
>
>>>
>>> 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(((EO bject)
>>>>> 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.ObservableListTreeCont entProvider
>>>>>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328529 is a reply to message #328490] Tue, 27 May 2008 11:59 Go to previous messageGo to next message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
Ed,

comments below.


Ed Merks wrote:
> Michael,
>
> Comments below.
>
>
> Michael Haeberlen wrote:
>> 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:
>>> Michael,
>>>
>>> Michael Haeberlen wrote:
>>>> Ed,
>>>>
>>>> I'm not quite sure I understand. (actually I don't know what a
>>>> "wildcard feature" is).
>>> They're kind of annoying confusing things, but necessary to support
>>> XML Schema-based models.
>>>> 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.
>> 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.
> 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.
I agree that it does not make too much sense. But given the fact that createObservable() gets called (by
org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue#updateInnerObservableValue()
with an EObject argument which does NOT have the given feature, the current implementation makes even less sense.
Returning null as I suggested initially does not work either.
But maybe I was just trying to "cure the symptoms" rather than looking for the root cause of the problem, which is that
createObservable() is called with an argument that does not make sense?
Here what happens before createObservable() called:
The situation occurs if I change the selection in the master view.
Once there is a SelectionChangedEvent,
org.eclipse.jface.internal.databinding.viewers.SelectionProv iderSingleSelectionObservableValue creates and fires a
ValueChangeEvent which the outerChangeListener(s) in DetailObservableValue handle (and call updateInnerObservableValue()).
This is all JFace Databinding code, so is there a problem in that framework? Or am I just using the frameworks in the
wrong way (which is always my first working hypothesis, you know, but I just don't see what I could do differently)?
>>>>
>>>> The other question is what else could I do in order to fix the
>>>> problem (and still use (emf-)databinding) ?
>>> 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.
>> 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-d idnt-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.
> 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?
No, you have different detail views for each selection.
>
> Again, I've not used the framework for any significant development work
> myself, which is why it's marked as provisional API. Hopefully in the
> next release I'll have an opportunity for that.
>>
>>>>
>>>> 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(((EO bject)
>>>>>> 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.ObservableListTreeCont entProvider
>>>>>>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328532 is a reply to message #328529] Tue, 27 May 2008 12:51 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

Comments below.


Michael Haeberlen wrote:
> Ed,
>
> comments below.
>
>
> Ed Merks wrote:
>> Michael,
>>
>> Comments below.
>>
>>
>> Michael Haeberlen wrote:
>>> 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:
>>>> Michael,
>>>>
>>>> Michael Haeberlen wrote:
>>>>> Ed,
>>>>>
>>>>> I'm not quite sure I understand. (actually I don't know what a
>>>>> "wildcard feature" is).
>>>> They're kind of annoying confusing things, but necessary to support
>>>> XML Schema-based models.
>>>>> 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.
>>> 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.
>> 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.
> I agree that it does not make too much sense. But given the fact that
> createObservable() gets called (by
> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue#updateInnerObservableValue()
>
> with an EObject argument which does NOT have the given feature, the
> current implementation makes even less sense. Returning null as I
> suggested initially does not work either.
> But maybe I was just trying to "cure the symptoms" rather than looking
> for the root cause of the problem, which is that createObservable() is
> called with an argument that does not make sense?
> Here what happens before createObservable() called:
> The situation occurs if I change the selection in the master view.
> Once there is a SelectionChangedEvent,
> org.eclipse.jface.internal.databinding.viewers.SelectionProv iderSingleSelectionObservableValue
> creates and fires a ValueChangeEvent which the outerChangeListener(s)
> in DetailObservableValue handle (and call updateInnerObservableValue()).
> This is all JFace Databinding code, so is there a problem in that
> framework? Or am I just using the frameworks in the wrong way (which
> is always my first working hypothesis, you know, but I just don't see
> what I could do differently)?
Given my complete lack of experience with how to use the framework in an
application I'm at a loss to provide anything insightful to say.
>>>>>
>>>>> The other question is what else could I do in order to fix the
>>>>> problem (and still use (emf-)databinding) ?
>>>> 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.
>>> 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-d idnt-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.
>> 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?
> No, you have different detail views for each selection.
So I'd imagine the details view should not need to (obviously can't)
access features that aren't appropriate for the selection.

Again, sorry that I don't understand the picture. Perhaps if you
provided a running example I'd be in a better position to try it to
gather insights...
>>
>> Again, I've not used the framework for any significant development
>> work myself, which is why it's marked as provisional API. Hopefully
>> in the next release I'll have an opportunity for that.
>>>
>>>>>
>>>>> 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(((EO bject)
>>>>>>> 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.ObservableListTreeCont entProvider
>>>>>>>> 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(((EO bject)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
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328579 is a reply to message #328532] Tue, 27 May 2008 20:51 Go to previous messageGo to next message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
This is a multi-part message in MIME format.
--------------080403010306060206020904
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Ed,

ok, I spent some time to create a demo showing the issue. (sorry, but you were asking for it ;-))
In the attached zip there is a demo project with a .genmodel. You will have to generate model (a basket containing
apples and pears), edit and editor code and copy the provided files from the editor project. I am working in a 3.3
workspace but use all databinding stuff from 3.4. I just added an additional page to the generated multipage editor to
display the fruits. You will have to create a model with an apple and a pear in the basket and then go to the
master-detail page. select the apple and then select the pear and you will get a NPE.

Thanks for your patience,

Michael

Ed Merks wrote:
> Michael,
>
> Comments below.
>
>
> Michael Haeberlen wrote:
>> Ed,
>>
>> comments below.
>>
>>
>> Ed Merks wrote:
>>> Michael,
>>>
>>> Comments below.
>>>
>>>
>>> Michael Haeberlen wrote:
>>>> 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:
>>>>> Michael,
>>>>>
>>>>> Michael Haeberlen wrote:
>>>>>> Ed,
>>>>>>
>>>>>> I'm not quite sure I understand. (actually I don't know what a
>>>>>> "wildcard feature" is).
>>>>> They're kind of annoying confusing things, but necessary to support
>>>>> XML Schema-based models.
>>>>>> 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.
>>>> 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.
>>> 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.
>> I agree that it does not make too much sense. But given the fact that
>> createObservable() gets called (by
>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue#updateInnerObservableValue()
>>
>> with an EObject argument which does NOT have the given feature, the
>> current implementation makes even less sense. Returning null as I
>> suggested initially does not work either.
>> But maybe I was just trying to "cure the symptoms" rather than looking
>> for the root cause of the problem, which is that createObservable() is
>> called with an argument that does not make sense?
>> Here what happens before createObservable() called:
>> The situation occurs if I change the selection in the master view.
>> Once there is a SelectionChangedEvent,
>> org.eclipse.jface.internal.databinding.viewers.SelectionProv iderSingleSelectionObservableValue
>> creates and fires a ValueChangeEvent which the outerChangeListener(s)
>> in DetailObservableValue handle (and call updateInnerObservableValue()).
>> This is all JFace Databinding code, so is there a problem in that
>> framework? Or am I just using the frameworks in the wrong way (which
>> is always my first working hypothesis, you know, but I just don't see
>> what I could do differently)?
> Given my complete lack of experience with how to use the framework in an
> application I'm at a loss to provide anything insightful to say.
>>>>>>
>>>>>> The other question is what else could I do in order to fix the
>>>>>> problem (and still use (emf-)databinding) ?
>>>>> 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.
>>>> 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-d idnt-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.
>>> 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?
>> No, you have different detail views for each selection.
> So I'd imagine the details view should not need to (obviously can't)
> access features that aren't appropriate for the selection.
>
> Again, sorry that I don't understand the picture. Perhaps if you
> provided a running example I'd be in a better position to try it to
> gather insights...
>>>
>>> Again, I've not used the framework for any significant development
>>> work myself, which is why it's marked as provisional API. Hopefully
>>> in the next release I'll have an opportunity for that.
>>>>
>>>>>>
>>>>>> 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(((EO bject)
>>>>>>>> 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.ObservableListTreeCont entProvider
>>>>>>>>> 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(((EO bject)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


--------------080403010306060206020904
Content-Type: application/x-zip-compressed;
name="demo.zip"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="demo.zip"

UEsDBBQACAAIAHe0uzgAAAAAAAAAAAAAAAAPAAAAZGVtby8uY2xhc3NwYXRo nZBPTwIxEMXP
mvgdNr0zKxfjYVdizJpAIhhYvZLSTpaROi3TlsC3B/8QjQkcvM2b/Oa9l6kG 23dXbFAiea5V
H65VgWy8Je5q9dI+9m7V4O7qsjJOxxh0Wh7ExY9CTrIrVsS2VlGMKj6WX2N5 mjSej6SXDtA4
ChHhzSZwOrNZHtJhNG3mD5Nxez8cN9PyL0ecUFg7sLjIHWT6vkSBWdJstdjX p3YXsBzpjZ41
vT7c/KNSsAjGC4LgOpOgfXa5I47nrHxOIaej24L4E67K3y/cA1BLBwj0pbHS 0AAAAHgBAABQ
SwMEFAAIAAgAd7S7OAAAAAAAAAAAAAAAAA0AAABkZW1vLy5wcm9qZWN0vZLP isIwEMbPCr6D
9G7i3jzECu7iTVno7gPEZKwpzR+SVPbxN0lTpYjgQbzN92W+/IZhyOZPtvML WCe0WhcfaFnM
QTHNharXxe/PbrEqNuVsSozVDTD/BY5ZYXzoDu6EKCqh5CA1wamMHtNSgvIl wUMV3fyBSwKP
1LETLa8MsKiy/AxRqnhyMkbbGgFrhXGAGu4R0zYU9EJTAOxthJCgtu4i22WN xwbBd5SnuIYD
2lMlTuD89r3Yip1B0pdAszOsPPB8ZyF39+Lxtvv3OEDqe5SJI3+3XS3U4S4w 1JF4vYXxaf0D
UEsHCCorfbzkAAAAmQIAAFBLAwQUAAgACAB3tLs4AAAAAAAAAAAAAAAAFQAA AGRlbW8vYnVp
bGQucHJvcGVydGllc3WOMQoCMRBF+4G5Q8AtNbmAChYKW2hlaaPJsEayO2GS gN7exG5hne69
B8NHWKmt5fgRPzzzHhuaGTfV9a5DQHj4SfvJhuIoqZ3S6xuCmt/IjoJZCOfj 9bDpL6elFkMZ
6uv3GP7HKBxJsqeE8LpL0pbH6ANpFkfS1iAkLmJJ60pJrEHgkmPJP1G3V/EF UEsHCMO5lKSM
AAAA8AAAAFBLAwQUAAgACAB3tLs4AAAAAAAAAAAAAAAAFgAAAGRlbW8vcGx1 Z2luLnByb3Bl
cnRpZXOtUUFqwzAQvBv8hyGNb8G9l6YQsAuBxg6OPqDaG1tUkYTsRM3vK1kt tLcerNPuzu7s
7ChNHvDcanO3oh+mlzSkj3/yUFrvu3WahGi7wAs8TKPVHaGjG0ltyD6FKlBo VDVDO3DVE6aB
YGyAJ0Ej3mlyRMqXxQgpFIGrLjTF2VWWZSirAvUrWLOrTm87VhY4NvWxbNi+ PME3rObBPE4c
+IfngCL3s+YOxS+0ATeGAreeNYRQn+fwLGRcGyVGngDM5/j+6xh1/ybNl7Nu yU/4j19LKjfy
2gtVeYOxBaNxwsGbJj1g9U10ZL8h51xOn/xiJOXa9mnyBVBLBwh83Ai49QAA AKYCAABQSwME
FAAIAAgAd7S7OAAAAAAAAAAAAAAAAA8AAABkZW1vL3BsdWdpbi54bWxNT7Fu wyAQ3S35HyjK
CrTqElXYXqpIGSJ1SOfKgitBwYCAVMnfl4stJzege/ce793J4To58gcp2+A7 +sZfKQGvgrbe
dPT7uGNbOvRtIwdQzsYMD+171SJVyRfG2oZIFeItWXMqPSLxDOtgs9ebtmFs /hLdxVg/M0TC
tYBHWxKD9aWjIRm+JHKYfmsfEnADHtJYQP/EUZ1HAxSTaskFkxnWuiRLOkJP pcQPITRMgT5I
5cackcY5/6zP1+K3SmrUIWhwqJqwEUfIBTe4I0pEf/eTYt19Pkysl/0DUEsH CB6MT1LZAAAA
XAEAAFBLAwQUAAgACAB3tLs4AAAAAAAAAAAAAAAAGQAAAGRlbW8vTUVUQS1J TkYvTUFOSUZF
U1QuTUZVkD9PwzAQxfdI+Q5e2LBFGRhcdQFlQS2qiMTuOtf0hP+Esx01/fQ4 SRXCdD693733
5INyeIYQ+RdQQO8k24insnhNrjHAD3d1EZ8X6UNZkOyhM6lFNy6LUg/25A3q mWjA+i0L6FoD
MVvsIqU/dp26yn0zKoSjihfJxIp1jacxk3yPDdC/1L3XyuBNxclurrWIn/CT kKCprqDTSFSu
R/LOgouSvate1RXfiJeyqK6dp8iPSn+r9l7/sSymKdB2ZlmyjymLuzOfgyTz 1ArQBrsAQnsC
QclFtDCerTWw5/zOwLbHgCc0GAe5I4ApP/eYOb5Xt6GOinLN+eN+AVBLBwi9 I54k+wAAALEB
AABQSwMEFAAIAAgAd7S7OAAAAAAAAAAAAAAAABUAAABkZW1vL21vZGVsL1Rl c3QuZWNvcmWt
k11rwjAYhe8F/0PIrjXqbkaxim4KwgbiB+w2xrc12KQlSVe3X783tRULG0xm LlJIznlyTtoO
xyeVkA8wVqY6pP1ujxLQIt1LHYd0u5l3nuh41G4NQaQGgtmSiyOPgZyUDC6u AbraLYIDYdoG
uBnSg3NZwFhRFN1Uxd3UxOz9bUFriW1KisdSMej1+ih7XYsDKN6R2jquBTTo ZZKGGUQiMwsl
AVTkKQM28zJKNFco3oNKK4i229XiYi83cG1pIJKnSjjyyiE8J9xaGUmsSTBv 4D4zRFUXUW7W
+Cm3R3Bnn3euncmFyw1P5sDxCT8AVhCBAV+ugkQmlw6ReZaBmaa53oe0069S +wGb0v/A2NxL
KRGpdlxqBdqFFI8Eys7R2XX2m9tUdL6zznBRo28qN3HOyF3uLuX8TOsGleiF O+4XyJ9eJdae
4dH4Xd6n5STLEh9pneN1+xj26mr/VzYz8usObRfa3afqErj5rak/APGNvxuX vgFQSwcI3fFA
LnQBAAAYBAAAUEsDBBQACAAIAHe0uzgAAAAAAAAAAAAAAAAYAAAAZGVtby9t b2RlbC9UZXN0
Lmdlbm1vZGVstZRfT9swFMXfkfgOkfe8uOsDmqKmCChBSANVE5P2apyb1ML/ dO20ZZ9+tpMA
YVRDQuQp9j3n3N91rCxO90pmW0AnjC7Jt3xGMtDc1EK3Jfl1V339Tk6Xx0eL FrQyNcjiCvRN
fMn2ShRPxnkwHh9l4Ql52hWhWJKN97agdLfb5Ua1ucGW/r65JoMEuEGYiIBL YR0kIaiGzmez
Ob2Mskn2iPJ/78hKsmRYCQTuDT6WhNagDHXIh+RUX8uuFfp6VZJYHUy3TAXK O3CeZEJZgx4w
SkKjp6ahYT7WcngBzI2yUjDN4QdsI/FJPGBu7COKduMrAbJ2JWmYdECW0bNo glu0Pfcytu0D
F3RSSNJwEGvGH1gLLrMIjdiXZJXIa+GscexewhrNVtSAFRsm99hB+MYxczD3 0/VtvtAeo0+/
kMy5EJ5KaTHV0nPmHsCPlt5UAfMdJiRjAX3oeWt06Mk3QtYIemTgGJRwEXcn WENASdKquPwJ
DQQbh+yN3rTBTnhH6IhNn7nfmESoNHB/4IfnqmLogbEm2C+DXnOfeY/ivvOv uFM21eFavRf6
IOaZtRI+CTNlU4viz8c518BwCEkR462NPxb6z58l7P4FUEsHCHcBE/zIAQAA lwQAAFBLAwQU
AAgACAB3tLs4AAAAAAAAAAAAAAAAGQAAAGRlbW8vdGV4dC9kZXNjcmlwdGlv bi50eHSVkM1q
wzAQhO8Gv8PcCgUrPYc00J8EcgiENi+wtte2iCwJaZ2kffpKaSgp9NLb7ux8 uyNtXcsGe45S
FmWxH3TEeJFajk3QXrSzSKJ1AkJgMlht16AguqNGFDaCE0X0bDmQcIv6AzJw WbjQK26M9pEV
j53iM43ecFRXqwvqSEa3uYI3U19pC3HQxkxR8i4M7pSv3cWyaFIo/JBoyKJm 8FnYttyqa/Sr
3OpItUlZTloGVMeRQh9Rvf4n0mNHJtnyr+yoOVCf1vLosBhE/Hw2y80yT4EX QzHimeKBJffA
G3cc2DaMLkxaIuZY52KxeFDqfvmLuwy+sSeRoOspvdzSyAlavSfB9rf2J58S o1r+zfmgPy/g
xsottWMKN9AXUEsHCKzEDE0bAQAA9gEAAFBLAwQUAAgACAB3tLs4AAAAAAAA AAAAAAAAIAAA
AGRlbW8uZWRpdG9yL01FVEEtSU5GL01BTklGRVNULk1GjZI/T8MwEMX3SvkO GehGLMrAkIoB
UAZQiyqK2F3nEg78J5ztqO2nx0lKSFGQstl+737vzvaaayzAuuQNyKLRabxg V9Hs3utcQrI+
qb143UvPXEEazyvpS9TNple2B7UzEkXnyEEZBjk6Q8vYoi4luEC6deR/S4bh g/gHya3dcPee
xqw/vBMOax5wJ3ZFYEE77gKAvYZmszZs0zZ28agqCepHHwTqvCHMKzI15kBn E6yM4BKPbUka
dyP24gt8eSTIsz0I3zgyXSMZ3YSk8ROv+TZLFuwmmmX7ypBLNlx88hJG2o1m J1jSsdPYUMlA
SKwsMGEIGHntUMFlNBvRwBpPAuyyRos7lOgO6S0BtLlNSX/5/zqGUFBFWDfk vcLpFQHP/DS/
RxYue6q1MKTs6OQ5d3yHOg/faayl6XLb/V/PR8HFWUZ4yk5KVvx42DpO4aW7 D/wNUEsHCInl
9hdTAQAAQAMAAFBLAwQUAAgACAB3tLs4AAAAAAAAAAAAAAAANwAAAGRlbW8u ZWRpdG9yL3Ny
Yy9kZW1vL3ByZXNlbnRhdGlvbi9BcHBsZURldGFpbHNQYWdlLmphdmHFV1tv GjkUfqZS/4OV
p0Fih6bSvrSKugmQLBIJCGgj7UtkZg7g1jMe2R7S7Gr/+x5f5gqEpIq0LzDj c/Hn73y2z2Q0
+kE3QGJIRJhJUJBqqplIP79/9/4dSzIhNRFyE0LEWaYgjISEMKaarlgas3QT DvH5yj0PRKrh
p/78skCxUiB3dMUh3FGeQzieliPfzMDhPJCsG2lGt9cvhXAgtJpSHY75vqZR E7d61OHifvkL
kTsGjyBV+M39vzBDETVeAIfI1+ak91ICuHkOe/tVHDdy+iRyHd5IFht+X+Q4 sY/HXR9ZvAGt
woFAu2L6SInrrsuj1cxZuBYyQWKGoCnjaoZCPuV6jX8zKk+mvKUpZouN+wnX AqhxXQrBf7BT
yYuIxXPV3PNeGqHcS5odr8bxmLIwZZzd8EP8mbkTwNqyfMVZRCJOlSKXWcah Ri3BSA4JHhCK
1Ckn/5jQTibZjmoglfDIrtBfZcRqkpQmUB+sk02StaPc2B2aNo5gb4augdDp 6C1TXv/kojb5
v/VsO8FiEknAie1ZgasJSjmSjEoc8fla7BEndEydwiNpGYOumanj94IW2S2V G5ai8+9o6PdL
E4e1bthKi2SbbdvU73vjSmgtktL60Vod2lCB9iCcs4Vi7DVJEu3/Lwgqww96 0F6HRJ2j1fuF
jiJvCtxMPeLfw+FoMZiPZ8vx9M7lUOdhYsHds1hvMc/5h2Ic4ZmyB2e2kGdd z4ezDEFFkmV2
EgOMaVPraqzr0jfET3TcLoIZDhpv4fV4Mnm4mV9edWtAHE/WW8fO0FxwKYUF 4JqpFjJQ586x
UgluN2Rjj6zSoQypzkSyaainMvgaeHOLxObon2AUUpsWCbsSMga50E8cgu7F BZ7o4dV0PhzN
v3z49LGROc2TgeB5kqpSP24dNf1sKgHtUzOhK+CBi+mRszvcxZ/OClezp/cI sWUvA85QPghv
Mb67mYzcqk1UqywFO/bF+Js6ukj3pGUOPbKmXIEXx0moM8kijxWlZI6gzIy8 Gm+lo4F18r4V
iv1GhKyar678B3sWr4R2F0RUce1j8H7n4NsoWGAiDmWLEPiT8XDKRMTA3eMF aXZBRT534Fqf
oLkGIzscZ7HtE+dAeRJ0exXMHqldK+EE94PEYoXX86/j5cPD3eXt6AgqA7kA 1WywClC2QEY0
rjS3ImbrJ5ethdG8OvBl1l5t2T2S5py730LC/wcpl7PZZPTwMJuP//KsvJAE K+C3ZsHflH9M
dyBxC0L71hRJgpfGCvcM0JSIdEF34O/Kfp8sp8Mpucy1+G0DKS5PQ0wS0FsR E6XzlU39/AQx
U3iA4kH2hjlZyjTDwvwNQaPPMG1GvW+wfQdy7tsPl/Vw3oIApoZM6qfXwO10 JOhcpu78epby
apaFpvxVpLxiFsuRhDV++W3flHc8JK9FlKu3SlrQYfPKZJxmeF9NV99xe2GN 8eUN+Gni9zt3
sKUpiiYoPx1Mk4j3Q/U5Vvn+ylozKTRGo73ertWbNJfUQ7Y6Dds9nE2FP/8B UEsHCOfVYFly
BAAAzw8AAFBLAwQUAAgACAB3tLs4AAAAAAAAAAAAAAAAMQAAAGRlbW8uZWRp dG9yL3NyYy9k
ZW1vL3ByZXNlbnRhdGlvbi9EZW1vRWRpdG9yLmphdmHtPWtT5EaSn9kI/weZ u9gRu4w8vou7
DzPL7GJg7A4PjwPGE46LiwnRXdAy6lafSg3Devnvl5n1yiqV1ALT+OzYXcfQ kuqR9chnZWZ9
9ac/ffGH5E/JX8bV4q4urqbNW/X8lf+CXv7raPKv+OOrL/6wyMfX+ZVIJmJW ZYtaSDFv8qao
5m+++AP+v5gtqrpJfspv8qyostHxweexWOgC4cf5YtmcNbXIZ2/CusumKLPd us7v3heyeRP5
uFeVpRhHWg6+ytjngxuA+/jiJygS+/xdLqeH+SL2adSIOm+qOvbtfTG/FpOe yl1jUcXth6q+
ysS4LBZSZOOqFhnMc7Wsx0Jmo3dFKd4MKnmY19eiHlb2VP98WOm9aT6/EjSX j6mIsyHmDwVx
X5RN/ogqPxSy8Natp6apKE/K5VUx71+b5bwpZgJ2XC0im72z/Ogkb6aDytXV FYAmD6v5qgHo
KkfLsmzXitb76TIfiywnTIEtI+bL/lVplz/M50AQBhU/A1KxlIAl4gGVzquq /Cavh9d4GFBn
YpEbhO4pPSnysrqS0LiU0PI+PfY1byoE62Ar9lS9KcStqCXSsOVs/lEgMd7P uza9X2d0JlpU
cUhphZGTIYvfrgxjvCkmQ2s19XLcLGsxeRCoCNkP9HtI6XBcPTQqqPg46Fy1 4TCe5xeleJ/f
VctBkFHxB7ReiweUtiWjZeVtk519PO/7PF7KppplewDlu6qc9Lc1mU+y/aP9 OGCmwHmdz+Vl
f0MClxURZd7UVbk7yRdN13jbxc2e6Cx+VeeLaTEGHK6K/pIlrWIGvLm0C9pZ +LaYXAkCA74D
T+pgurwokrTVpWiHDCymaMuAwrCNhpWyLUZLL4tstEvoBLRcxlvEMgcTpJIk Ga4qdJLXK8uc
dU4vlsEW+ikelvpY1dcXYj6e9naIH0dA4rkI0FXW8Iaz/Ebsyj5eAoUvq3om M0HDyd7BgxpZ
T/NAirPRt1VTWQmwqySwPtq1Ysi0U+HDZdkUJ8ABvTXoqoLkRYJsMocpbgAt SmD9hH4ofavH
zu4G1EU4HlZ/FG2gv4lFXS1E3RQoUZ6o33dnUyGaAd2zul7VR1brg1fMLmG0 sxnINPgnBxL6
TS6L8Z56ANlrfB3vNlJTV3po+Ud1QpUYGq6qPq+a4vIu09T+HchxVX23slNd 6wj/FOO8D0NZ
LVgRhUTfiXLRRST88oqVnuTzISsF5TVmwzoDWZ6tRiu/tmLg2Uj36gSxlXVR 76QNAvTnal7J
phivHh5Wemj5D6ejPngEqS4HoTLeUeyHvCwmfeK6K2vUuaxfue2pcCZ6V0HV UvYETVd6RZCw
Dv78AL96+4D9kE2qWV7Mgx2PO6WYX+3Tt54OWQOPqDLy6gzZX1R7oQsGMI8a MQNlXFzlnYps
uwklJ4nJUIT3a5+KS5LjbwR2bgbQamtga60t8gsaBezVOqg3x1ZKIjG1uFiu 2uy6rbEoS01L
fEBQOOuXGXgzKHp78CjKsg9saPXmZm28r8Z5yWT4AVVMT/mV62llxY6dpvGx XzMd0M77/EKU
j2jlw/wWtIcFzGJMS17ZjiIQ8PBhNIz/RCoOIi2ahWQHn2G6JmLSK25oo68e 4j48PXz7210v
MxSs5QLU0MNqArz5eIGWVWdK/kqbqM+nhUzgv3yeiM/5bFGKpLpM8gT7T2bV RJSJ3vfKgv3l
y5fJhbgq5i+XUtQvJ9U4efnyrfsG42x/+dsVSh95IybG0L28KItxMi5zKakr hUJf/GFD0FTJ
xMni8LJAuGaoXiZxkrmdtO0l8I5b3ODRZ+Pwwonxyc/QDc3JhpmUayEWMmlq kJ9wSpqpoJmA
vhNFvuFV3uDcwXgnSVPpsnlZJmMyjEh6CfVoHjPVducMbnRP4UYwhxs0iRuw WRoYM3Tew7wM
0JYvtQYK/yGQ1VwkuWonuVQNqZGBjpSofYljJxnaTMjaBxZnTwZOjg3xQWkN JdEqSrIApFsn
vBEVyMAQakVtgPPkulyCzp9lawWxZSgOIIwZkh8yvy9kogXnNY7CWeAC6Jmx LQ6yVv/uEolU
eO07okXzLQA+F4gDqyZSURo5zSfVrXovDbVLiA61FiIzTeGS1PihFiXR/2S2 lA2MEmrUNbRR
3gHnuYQqCtEb7BzI1i2wj2daPzuWnqWb38CMqaHXFRBYoD96XKDjArktykk4 E4aVUgk5rW51
DcAzRLUGAHimAap+u0eHwMkEIVRg0arTCshngrDh9uxe+Epgp234dt17aG1S CTl/ARt2uSAJ
pRijQLLGkbjjC4Jj4EyjpTY2FPVhDBIRYAlxQNowNMLbopmufzzsNEJB8+C9 g2COyWYsf6WN
9BFAUFZrGYM7Il3lpEiaTbTI52Lb4PRFVa2VGjmzUjJe1g5braFpMPSG+qhR bCe302I8TWb5
HW4mAXMCQ0NJS9fSR0RmnMiMQLiqo7x1/UzVMFQ+BbHhlyRTKz5B4xNAns3C oSBDc7FeIabj
bNVxk/ah66plRMkdJ/7nv8F8Xz/mZPdeKlYNBF9PEorMpAVAd1aRWqO4bBxz /tIJ49vOKZLJ
TjIH6mE9g3oaSbcG4oWTVJgSBTucaOrttCqfaZ/oft3zThI5js4ODk/Of2wN TSTcUIBbvBZy
AVygQFaBctO4FjnphrdG706MOQuwH+vKRHt0aUAR5w/U9gKJWVuoJeHgOmfE G8iMP6jFb9tF
4kttaAAO/nYqFP0ypOpCjKuZMIRgnevLTxlR0HIPO1BwA0fklUm3SNXf2NAm iJuqmFA9tAze
YC+pfyaZLEyNjeIySRewbLLJ52MB29lX9mw5KpimwdfFVnYlmj1FW1HsB1B2 diLaoWtnAyrE
LJbpVibVlxttfEydESVDWqOXjP4nba+KoqcxhQkrUOl79Vf/EaUUSWvcnk4T Dtv/2DHqlg70
VINWTQCxmpTCLGm6enAAUtiYBaijMdXIfXQzfVNXy6tpc16dV4vu/fTVV8no ao5HFj1N7ZVo
//iFjeyLfPX2HtTS8QKw6IGN3Af0wzoAKmY5zW+QYgAJqWEJbgCrZQH7LClz ELg13Eian4dv
GuDeGmgctCF3tEVbFLJzhMow+P9lhBqaJx2hhF+TZx8J9fqYcRzmC5TPJKC9 IBY2sQewIKLI
alwgGEqhyi1LXy+DXlh4txN3HvzW9n5eubcIvxqt5x8db6E1eu2sJZGDk2qi DWQoigDBn+iz
fNQyl+WE9OHFBOFe5wSAslcK0L5VV1owGjlgdkDAXIZqmTYQW1u8qtw1HhJY rEcyiesTge4S
ULms8sl6BxicZxsA3RDNh53EyDBBFSvF/O0YNK+6mIgWsVYuGVpsT7lnhvqk Hzzhhn9Atq1q
UXeM+5ut5TikBPQALbBV/x3IxCBej/ZTUyejI58txu3HOTBh+/n04Oz4w+ne wadPo7NP7493
9w/2X68qeXB6enx6trLYx93To9HRt2evXd8bppiT1XcSC+tW93RYQWPDYRen HDtJPs/Lu78L
05YR79Pa4uV8WZasIZx/1wJ2d4ZaddHcwex/ucPQODv+ns3fxkYHWcgWy4Z1 59pmnd7bXyQL
DWhUMUXbrt+WN5gO9PVAx1EWKFPReKeiLNXP/UIuyhxGnuXybj4++CzGrtJG ihhxupzP0TSW
eg1ubCQcCerlPPy+0UVX+KpisXv2lNxHJ+0ClL5r+8G8jwiZFlGWIPVmPmp6 2BjKljEkt3SE
hggy8Xlew5zZfZs09GzHfYF+SGe2mP76ZngXy/nATj6wgmE3bTGwrUZa1Vmf n67VMhAPl7GU
IHjttMl4vahe6bcFUnMktichv2kuPx/Py7vQeiSkFqixAGIX1UJUOb9baJ3K j8jJTo7Pzj/t
fbd79O3BlqpqdqFfEDgf/ruT2CbptUOHpr5j5JqO7GOxPwk/pY8WcHjoloF5 g9npwt87/rk1
gsWKclx9Whl3WKMPVw10s2pzGAnnBicmjS2HR7SINdCaIk8t8yupWEKw4Ie7 p98fnJ4lf/yj
q5rA/2xVU1zR2MjGyd6N3h/49JJ0etvC9yBDQZ0/JgHQmdpn+8k/QqBODw6P fzjY3yKAXwW0
OMZ+2SbwYP5wOsrIyCbgF5sOjMbKmymMqanOmhp2TLq1tZ1c5kB3fYqOQ7Ed ATTEgAPm0DHc
jkHFxoSs098cWT6ZxBgm5xnqf9Yg8aWvz7S4bqvPcJcP7pM/sN+cmcOAQIqb G6k7UkJv6yiq
oPUnAC4NxBdqPRzBo3o6DaY+2lO4PhHOzrqMUrIb/VehfawIIyZqO+VjDF1I dU1OFWjB9fss
OoiskAezBUqCfDyxfbYLElRvU4HE+WUh94s6bPnXkcu8TpWpENSFSnZY+6I4 vhGa8bIJgAxt
PFy6u+9eofaGjq9QDCuDFWo3FaxQbFauAjvoVq/98tdazy4j7AMWwPsLIjIq mV4ocCLML9b9
uZCNdvWnCONsdHR2vnu0d5CV1VXqakStwlFR9TsaimS2uuA0C8Wf5oXkJiMV bLJGCZZmPpxk
NQsgJJ7iEQyogMoGAoxzklQoWIIa3yhZ8itsjvZYp6h1Xp1CRRRIQfdTQgfj mkm3jBZUBDwW
uT1IgooE4CUwqCloyneJdlpVtkR1WI4HSDAruPUmOL2Ax/Q7Mw2ovxL1ZM0L CFfsg0YkjcaE
wi2K2cJaLKamlMjiXjW/hE3eMLT+ZVRqBXVSW5CrjC2Q3UxGKYz/ORAjvI/3 ena42NFqrjVB
rRIKQKRqfme6FzWZbSr3Jt6aB2EP9Aj3fRxHb3EPgdI0qbQbjDa5O3MfYO/z GN0ZhnbJQCum
HYR5zqSTf/wjiW9Psz4tjORxYLBVL8ulnDqlpNvGSttWrQPq5k7xtyL065bM 5hkTra28kO/J
pMp5o/24nKO9tUPZtKWoDMs6oo7pPx3unoRE3HAJlhslyiM0PYgbufCAFKZP fi/u4jL3MJPb
ahugg8wxwKgZ6X7FajnZvN+6pfEmSTjmfKAqkhvLpWctRzTCj8Uc42XVy4mQ 47q4ENbvUi7E
GM2jE2ZqXDtydY7WYdcKO2QQpedZcdUKoBQUlNJLlHpG2W39NtmEyWx06OGm ffvK/kIW6h6g
dRWel/z3/yQ/rzB7WEmJcJKBTS6w7Pl112lRdpOXS5IzObIG1Qebn9lSo8YZ NBM3Zxbzhk4+
TTTmFar9mpnuVcs5DvNl8vUby5CDwm9B6Ua6CFU0z/ULbAWuCn7kp4WdPBWC b51Nku+BG1ja
tqY/0n5vXRpIlAh6jXgaWF798L5awzXIzt4ohbZV0tLnVo2V8xKt4bkXcSck U4uzAdhYNDl/
/rM/Pdtt+LfdpqBwe6ZNSbXBzsXnJl3ZjpLt6uYonwm/jZWLtYEeuef5hQwc RQxjaqUyiLGn
B2owAX7B7uBzmk1zqSZcdkv6RF0cTfDqT0CmbsTAJn4ZOnjs3wNC2f4MEJHT rF9DTWxLoWfk
j50nKguF9gaV1xJxdqzFNbTqmwgxd7IOqsA4r9d89Gwsz1EhUk2NspLRIL18 TFm1EPP/AtaB
k6JJaMyuoDkbmXOUPXbz04fRJ0yEYbr6VGLg52a0KB7TeoU31Z66jxweqT2B 0x1EKj71/ClT
h1PezFzReZ5G9AKQGiaq+Lvw4u/STuiBmkgQYGKRhZfaBXzNw/Jlqc4BWJvC Hs03xoqGgYK0
z+8KUU5gpzdiZqNvJDM1+FF7mtfEI/zS+Otsn6TOBU7HKcyBBHph0dYoNX43 ZHPz2+Y22+4Y
W0PLBjXXH677oKaGxNSrBv1VUSEDpOyhkWd8rRbltihL7QzCvdDR/1qXVv4v 4rMYL7Vnj16v
VoYTU0M9qPVrFUoZaLuTiY6coUNUdLQSjd7ZEg/8xngCqltF89nlpdqQFUnE FGFwIeJ+5Drc
gJSTy2q85DuNw4nTHEuGQrQn1Vuw9dWZMz1DJ2/YnOpeFqDnJSzpZXCkS/Rt T6mU2PAKw2vS
bXZN+o2uSXJZ1ML43yrwUpbPKTs5PT75tD86Pf/RO5VU9rhzRONKz7MKaQlW I/Nr8Cc9hbSs
p7Sq5s1Ogp7Qbta27DHzmT6MpAk5DCt69uKERN5249FTPN8oeF5pr+dWbTKj 6yGqhfOt79DQ
fQhCy2/ZgIAKyZetr5le+boq6YxgX5n7JsFxCy5sq2qt7KNpF0Tsd+IM6Pql etEmEAGf0W6N
pLrDHvbIB0MnT+QzZ93dIeepT+e2PazZptptN8VvlGTyNu1m9/DfVNTCckdO V4BKUNge/Bxj
HE/RPD2/9N1kAu4ZQT1UdJVlm4sLWaSkLtUrKYRhvyb46rlirxjlieIXO5P9 61sMPtRPeuyK
SvqFYEg8HmfMkw7Tzj3Mr2HQS1hzOl2prvO74OjCa4LjIv/QNmOjmzogAUap Xs+rW8TtRodT
anEcqKt6NRGXsOY0E1TvQoxzmLHkFpgYJg9Vvs+wGlcY/8cjnEjIH9M32Cxj EKY549Ieqipt
omkcsW8qdCXmw6qyLsDOkU2my/I/hlsg1OoHs11FWEkPG4lyAhTpbJCiDg8M Qh39A7HMNWd+
kZmJx6HEqLdXIPMOd3AokYgtbwdkTUU+OOQCgjbRbrOq+mDmK6NZ6DpaICRU epGMkdEcv/7v
EvAats4djyGMpyu5R/QVNcUU+vRN5XTJYVYvuUcV+YEh/mM68HEyE820mlAW Dt1PDzW+Vz3g
zsI2dVA2thiJc4zkT9LcUoXk3K+NsPhJS7QZp6WEaBeOMKdJuGBPD57xewNi K0VvNqTEpLDp
L6V0KgK4H+I+kFswG06loR4Cb9qbW8Ugp9J0g2/8gHVtQ/FcU/W4nMEcN4r2 Okz1WyWtGsD1
S50tYidRPFjZ9+BNqktrcqC2V2pKa37y16R99nR2cJ689t5L2JGlaIAkqepb W44c/f+YqT00
zwNo/5ypyEw505h8+nnShTXH+7V3g4M1OkANM4d0/QTWCJZ7Yf6FlCVnuLE/ 2QFfK2MDTnOr
ZHdRTwZplcjQnv8O7Qsp9+RQYkS7Pd6znbxICG6rG1gT/a1bAZqBOCyVPEy2 HUwkESac0Dkm
jI5khDXMLGESS/CEEtso+hYoxEplRdlW/Zn8Trp6NV+/SuHPkJYR1bCcCXJE 0KLtFzUnoCMq
WRbTCFoyptcEFelKgGDIGPfGZ8qz1Tfp+JtMCKaY+tvdrhY+KYCgK6dCKIXj iv+EyZpUhAgd
0FcSQYFhs0QT1kyjRU+pZeG2CO5PuA9FGs3q3yp24Ju2aGs7WTxaOou5ZXki uUUpowadNdWi
FQKRVOXEbEQ7qtVaha9SKHelziXoWsGtCIh4XtqCEVc4BuNNHDid0yWfTJ4A pFOQg2YXaAbw
lUR/fgxCvGFj0UZZpbtJZma4yDGesvIVP1X/BSvndeftiKBvKyZ05t5AtyJv xTqc+lbqaHrG
e3QzPx9kWyl7elKnp4HRek+tCRPvrDj0ItL/uQF1cL60BN8MG9Q92FWSm99h Km4FzH5NJyei
NlqlrU+ai3wOpzg1iD01AEzT+a6q0/CeD59ys5tnzMjxlTZHsq/p5r+cVIsP i021V1hZ8lEh
O4K5lybdhFcFSaX6nNErL40L/W5ZfpyKOZ7uzlNnWAja5vlGU5eRgsDESd7h gGetOdBEwjMa
qxYiH8iNAithw6qUO401K8wbZ10rG2xPFl0NiT1lQkvmZD6xSWQx4Gn/aD/b xwOFveOTH5N/
uGeMjeHP70dH3xN8JmExKCON/mkip9innxMvuzEOeqT9edD/ic8HTDkmND5T Jo3Ug3Db9aGG
20qAzAfpN1kthjXZn8rZ95TYTnh3HeZthY1o3CErtgplR+dHlntAmX7bVqgX 0hXBUzaPdCvK
/gJteIvlGkzj3hmZ8tTAo2tD3z6cjixw+HsncVmUcYExpCvuuRNx4UiYEhWL ILMfnTMJ8Dj0
QdWu8CaCdUpZWiJT6bEz1nK/64sXrsZGyy2RJPJoDxU2NOu9y8Yo3jxV90xv 0dLC46PWA7eY
R7n5DPOefYT7rPJm758lYwzDoB1kB13JF2JoeqrFi5zPmnaENcwUdG4UoZD/ 3ub1nER14sDW
UdbA/4W1y/rus24TpDC9+fxua30eLSzZScdstzBsO+l2q/K8qnHuD2g2eHwU urB7RT7qWYoF
UYXOuRfB84M8dClPxGAn3cB9ac8RNRrTp5nyjdrcTvhgkJBtbXU79zr8tpKw tsFsMb96V8yc
6wYDz2aivhKpveQi07E+zBPTLRdRH98cddG6miQMBXEgBCoLcw/7Lcx7MO33 W8FYPYuXR60+
Gb+iXo3DZ9qUfUZrGZd1PhOY0gB5OHkkw3LfAcQJyJAkCGLmnadHbe+MmrFl 7UZrI0+sbUMy
V7PLuprxM0wSF5x9xWPtzsGAMhaMWWMV2aBUNlM6WsVjezxerXCiFKnMG5Nj F/tSpktnxfmy
fQLUy/F8GqNC4DH4/cv0EQ1h/opXyi9FH5ZEqRPziFP2NaODOf3ZpuT1RAqt /EcNm56tiFlB
I3Fn2z0xn35CD2f7MSleCW57cq/vykNHDfWLW3gwva8aiJHVhUhtye3k7ON5 dvjh/fmIeaqw
lMBQhT25JnTn2DCraGzPvFLLYNQ5Op1143/RS3XXhnh5XlLKWh8p42CIWqH9 BIOB6WrDrR9T
61BP812/nNtVkPQc3aTcgLdYc8xW8CZaFRXB8Eiv7aATlghO8joBw9a9a1oi bfvfIy13tKsE
/WH+5JHqq10DhgvMDOt9xwG2EpjbpmhKMQBixx67bgtKwwFhRg5ELOi/fcqq 2osaTYJ2rP+9
tvmDXCs+o2Svgyj8nRWYGfwoCVt9O2TKzl4ARYwzd9seGSeO+ijsn5Txn5Qx Shn5bQkPIYu8
HmWKXTbVwecF6FfvQSUt039/1VUyRj0HeU50kLqw/V9MP3vQn/f1LLivDo77 Ed+7boXjPrsl
4reL9Q4R2cUTDu3bqPCbRkos7i7VQIR0g+5HSFfryUSUdrPrxC3X07NgFs7r I/HKMtPfCV4x
Lvh7xquGc//BjM7VelK88pt9IrzqFYFZj4+Vfl0Tz4KiCONjUdReNyTq37DI y5HU3Uz0+8ZS
dhsToql77MZTVfNchaQoh3x+kxPtd+WT/4YVfZ/fVUtMjkB/dtwsqw+pB5HC UnqvKrS+fidy
QE5MSIc9ca3WNQBDlWEJBpG6wUn7B+oHBpd6k1JzSt05Oj46sJyawFLxd1hu P29yHXCHjx8F
hk/Qy3/fTr5+9co3VW/wTkn5RtwMEPKYlQmQslUftPTi73n/QEGbvlzfMP8t NkzXZdcgz2yJ
cIh+3a4B8o1HHAMr6AikQkhjPkGzLJrLN/PN7WTzYvM+ggBPy3H8dtcpyrGu nodRYH+/iFMw
ke53wi5+/zJdKEixO/CGCniaJDHDUrQ5JzAx6c1xBEuC3hVlaZhHWLSHPZjG ergDFOlhDvYr
SWhtmrl+2h4r9bGYNNP03/7jVXQcbdq/ahTrJN3tMhr6V69WbLXH0fjulp5c vwh6WCvdj3X6
bKoC6zPOC+Bf+oelvTFAmKwShzk68u0LoDMltaLIlWkj6U4rxL3Yz4/3jxO0 iL60B8a65kVZ
ja9VOZEtAP6GwrTP63zM01LS3wenke1KZdCXxyDxsyxZq61NGcsO8fEPjO5g jjER2iWeJ7mg
5BeU9nSiQLTc9oVEPqvr57B13Dk1+tTP1HVA+ZxiLLCCKor/BtkcSO6jLRLL LEEfwltbNkys
0dUyryd+ssWQAfrZJ6g5IhZikurWY9cI6DN0bJ7frKa78zJ5T6ErL1+VK8fB 8tMfufwCD90T
HVuiZ0esvLDDy3kQemmMmPsBRVOYBTXuWLNl2RQv6Y3eNXjPmQ6Doc2EM6Tj 7ylwDXdOkjf6
ZtqmqWbrTyJqF8k5WgUp8/6yk3xtozUZiQJ9Y1O7QptqbPt61xlCD++qcuKC ZTbSlL0MBB7i
efnFd6TfpF+b1TipiK7SvzuR1CdnsHft0gWfpf5MtTMgqurHXfLn5D851Yx4 4/B1bmPv8MVW
FyprOVw+8zK73HGdy/y2c5UfcEi7xn2AMtL+wbvdD+/P17ojXq7cEUbBMleC qWtpWzdNr9kD
y19g3HksO4gVH7wEIayQK/DG5bFuXxkaOunpnMNeORaT06r/oCCbQt037vu4 TQQwuBnqC/pK
aBtMg0EnLpPBGmYbffWB+0vrSLq5nI+nYnwtJptb4XKEcbCGNe9RfP+1uGOY B08ZKJPABNPR
XnvO/KvMtKaLGMwuVgXE+qvZ8X51+PLaD7F1zpe845NWYqBov0glwpIsoUW8 7W+rplIZFeON
IkEMmvAHayKfzSzi/PXuHbwFQ0oVvZTDIgFaiFqyrF7BpefrS+YXWdHOhbI7 IoJ5QcgoGXba
d7cb4SMndd6PzqOdd3gXgcdkkoh8+nm1sOgZK5ydRofcuwy0S5de05TWZYzo F7swWFFyZtTp
Ld0b4RhcWKwDEnVmxJYdjAW0Rnt6Sp21s4cncYnrbH2oY5ybMJcoCR2MF9Vi uZB0n1p7zmJq
cteN0FyZeJgzXeQ+FMoyd+aSCtVVZTIPGPHM+YN5KeaSpGumnsUHkKk+K7EO Q/TtpdUYNJaO
eODizP3eTkbnoAZ+k9fmY+M9wnfQxJulRCucKSLDNyEet/v3ugy7aLcX35tt SHbadd8MnybJ
7viGKXK/dcI0/BkOza/DyhmQr7ovDp8CQfu2rC7yUpWQqbqco92Kn0s5RvBV vGmEXjsDLsab
EXVzebSQx8lK5+QU5PqupDSdz8Bl4bvVSc4sg2iLHj3U9AtneBmSaSAxJxGC 21AAQA2cBR7T
hdY1/C7vMlfX/HpEZoHAYGHuC+oSWkVfKoEO05AJq25NYMROMEw8MWkaQc4D IWt9wklLlusQ
8Jxo0s5MGUgmkQJq0iiSlSQNMWl34dFPt1zhMc3K9IB0LeJf37rdwZY+vBUn 2oCr+KannsrU
win3MIAfQI2GkqOnoUdBwrp2nlDJNoYJ3ftFYo+PPK0Ou3BnInK8SBwziqJ6 CCTkNucJRAyP
N5I9kkaVuoSFDKEAsI5Ls9hi95MZRzNbO7U3gRDlnHT5MLwLfPgUWCPLKCKs mD02agRlJ3D4
AkTT3K2KCXWjlR28WaEbSJm9J2wIrwU4QtORE9GAF3yrU4FQqknbeSKc9s6E Sa1GBy2jaBD2
NaeOrERpEvm8CNOaKkF/G9/O7RYqmiAdpcxnvFIutenOT0diwYwuHD93RVIZ xlFYdHeXuqrh
MhKGb1tXv+pSjgZ5xSnmOJgeW/J2WgDLHbJSA1o1kx6hhSzlCwtVU0kFbovJ lWhaasOj4m88
GLd8Ccu/GJtBRCGHK6BZuaIqawTlEUAMDSfcTWN/K1YX61qxWL4wEybUVWfQ PRLG0tZKA8oT
i6q03vcUQy6x1F2C0bWynQv+WcJMzamWu67sZ8ZI0rSVKn5rxW1lqEae5Tfi SAi6P6yL9Txi
nvBuOS/wFTDv+WJxJxUOi4x7V2i6PKzm6jDCf3aRulhcHWS6a+xIUqfkw8C+ l3mJMbhKwGYZ
0VTaZUy1rejSdmKpGNQ8XphsLjwpd1BSUzJWnjI12Eujj0/OR8dHn852fzj4 dHz0/sdPo3f6
3vH97WRIqU+HB4fHpz9++ubDu3cHp4ZLwKj3NRFAAzMKFphqF0Rxk5DFpmJu 9CbIk7KCpcek
vrgFyMxfNPp2Clhnk0VNNXkh5uMpm6qP5vr5Qyx5Z/O+sA6VxIxz1VU45cw0 EiFOoFxhPu9i
flNdA2u9RVZHEpDtBgYgAx7Wo0vrmxvau2nm7aINt5F4FgppSC1iQCLvQEOc teitwWwlFfgH
yJ23Az7I8hJczZeqnsJcEbFobCxUyBPU0zDLBr+wD2UyH4pCmntJ4xf7efcP tW6g7LpU24KI
5VOGKKyQS9zfTv8SuZxovXcMMmjMknpn/R2XEGrMHHJppJd7R+VmW+rEbNVC Z1MickzHrYbu
eXYPfRMZ39LqJqLotUNblMIbN6ZOeLPtEIrbZcy1sypZH6r7ec1vxTW9P4pd 4dKP5H41t+eZ
D7qRozM/ULhBEJFtKoVblLlv68pkVVA57Ocv/CSAD7rt6r5/mS3693pm9CXo A6JH+p5LCIEJ
SC8EkMKFwWRDmDBhlDa/uCQ5FuVM4+yMUYG5lJrWY/1xNQf6STcW+RkuwqxZ dE5M6e/xuitk
N0oelU0t8lmWPL1q2rqbixOzFl3VO8CUhdfLsunAPBJdzwhwDf+gJFIwX3tm uvByYzowYG2l
nCKrxCtMy1T9hHkuLZyMc+gppcuT25cSx+5x5bc3AEWshS2tZUzVTad1r7zN 71iSSADFihDK
CDuvGpOEEWVElQRuHTey9UrPyKN35W5ZVrco9XpStJm/+PhkZS+We46sb/3i 7a51Y1FPiniT
3GkflODJv8eJu5VATTG6jU7vmtFJ3kyTBf6z4zWvtzdsCXNHGxpKsVywP0d4 4ZySgHasyCo1
ocQcVUba03JLVWlcwXrUIkMBaiZEADslgDAapU7KvMH7dE1/iEqkhmC7UBdH lWJmdO3VY06l
VO5B7Jnny8OaWyEWrTFrt+/XwoeXLOti2yheBJzeiPRbz8jjzuVQucZpgh70 ltAKOnraHtEl
Zynvy5Sxd3myj9gmv99zlTKmhf8rz+yrNml4EKaMDiq/l1r+YbUyZeTnvaKb yBfWTH+E2yIs
QNBrjTJUICOkYk1m1SvrS5KO1N9E3d+pF9yxJXc/KUUx3C0Qq7RLysEPeVlM 0HSZHe6efg/a
oMUg7b0OS7/bKFM6IqtryL7ljcBm+bR7fn46+ubD+cG2QknNfuhuaN5Y6zoa vZehF4e0evfZ
WlamPjB3v+m/QzitrpMSwngnzpSCTbfUgqvjgrP4DQstKD5i0lfMTqrzzm2t MEwNvFD1wfJl
hyFH5z2dLGm1JWbZXi6ej3XhJZhGQkc2lKhMLiuomdQ8y8U0PSFhwkY9e6s9 vnGBS1TGBndl
FERQN/a8d8EeVIUVTA4aMCWU1mKbqqOvYYb88irz+8nx2bm28qyZFHWtpzsS HHCIY/Zy1KjL
TxZDfzgWJnLlRS8olhVWjW59o73I2L1MP1FacnU6IrNRayus714mkzuw05eg 08vAJh63SBIv
p+wqJd+ev7kJWnGtwBPMkeph7dOEmi/z/nQqBHReYwZL75BtPc4P7gjWd/do XQEGJNp8XeN0
qCtrh8zFHrxUyS3J1EEqr3//rrtEZM2n3N75XM+hdjCNCTsI1UYzsu+u3sDJ 65bjj928hq6a
slnLRUgl5Y+4CWm/CAc2I8AyJkT7biLPdm1RG5CeSR/i2If3YcbuNUGjdutS jaiDrlI9Vvnx
vU6G6SZvXPxBG9aAf3p37Ax1etjoukB0kMdDU+FuczkybwsSWl0rmaQoEydF j3Ng369esxP1
cFjqigVKNxzG9R5VSno+02e8m8y4fgGKwnUgU6vevma9aXWGLvCI3aiLl3/v Q+tX5McROOqQ
4oSn+2x8zucjPPh/0MjOSHMIRrdNcK4a40Rc5kDyHjmlhxia1ep3BLsX61kr SHtFV4DF1BnP
56AXNhsx13s+X1bVtURH9Rztq7ic2sdpQUI1cAr1I1vYQOw1HTQvakx2YC8I 1ZvLzbB+4eJb
NBft1tpcXRPUMXgGWoPeRrdoOpFN5PJCNkWzXJMEMXgazOl2Ir9+1Ixst3K7 y6/jAaiDxRB9
3+qI3yJDAshUlAvcN6WLkNG3/mh/uzF3+HYnHDgMKrZeUQN72L2ols15hffj dDq8G8tf6o0Q
owmduq3YT9xrcisLe+KNPwu39xKJx6BMOqH3fWFWNjR8Wp5l4NwnNpAXvIF1 u7wGtZ4F6uBm
Wxeopt8EwPtM9texV2CeAjoPU5CtPmr/YrUxR6mOD7LnRKP7tXFJNddrX8Kq /mxmdmBMkFy5
W25MqkBy0eRpinp8q4OqzuZ773puO8N/ucJb3huA19bqcNxIBEe0NeVY7n3q uIHGnJ+H13my
C+wxJhY6defouC/XGcFuDjDbIbAdB5jw3/8BUEsHCNDxV/vnKAAAKtkAAFBL AwQUAAgACAB3
tLs4AAAAAAAAAAAAAAAAPQAAAGRlbW8uZWRpdG9yL3NyYy9kZW1vL3ByZXNl bnRhdGlvbi9E
ZW1vTWFzdGVyRGV0YWlsc0Jsb2NrLmphdmGdF9tu2kj0mUj5h9k8DVLWSVfq UxRpIRAVlRQE
bPOwWkWDfYBpjMeaGUirNv++Zy62xwY3tC/2+Nzvc5yz+JmtgSSwFVEuQUGm meYiuzk/Oz/j
21xITYRcRxCnPFcQxUJClDDNljxLeLaOxFKB3LNlCtFoUp5vfpl5y/JQwAPL f0eG0iAT0Iyn
obB7Fmshv/26QAU6lDMHfVwGbFc1EcOH+4pLtfOAVT6cLL9A/BPRnmyu5S7W O8nSe2D4boly
xYH5FDsZQzTzh+MMX1Ysrodgz+EFpIoqJ8Zc6YUEuBOZxhqZSrHnCcjfF4gJ HrMlpKdIKrhH
c0gxUFiedxuWrSExVkF2GnOTd7hHP05hNG5/tufj1OpFR/PHRTsyZd/ETkf3 Qm57WrN4s23V
3CAfYAhPIhzbYzvpC0/WoFV0JxCvuG6phJDUuH2casejFepU0cB2mpoy2aK6 pBw9sAznTGJs
fYP0wTaxF91PRfz8BsPcpfUEKwrXjBULIdJnfiqH1xFORTsy+0w9h0PBAgf4 mLrB2sDgOY16
eZ7CCE/HkFNg0uPOz/LdMuUxiVOmFDFSD2ND4Ct2QKLIEdR3I6OTS75nGkhV xmRfVHOJNMKH
CccpScC+bhyvM+C4anoAnhZXSQ1qwV1jTafjhJPbFqqoVN55tQb8PdmDlDgf rK1CYxogIXvB
ExJLHILgZJjc0xXPWErCSiPb6nxJytonOZPYgd6koBiI9u/bkDPCCvAEtGtM 6/hqIMq/bwvG
yBnl8dTpuST+O1qMFuPhU783Iz9K2GA4v5uNpovR5JMT7oWau2eByaUXDyKB lLg7Ql0cEA1A
xZLnVuHFYgMkxaFIYpzTjGeKCMdHVlJsiUb01op72QhlcmVjT9BOm3czmAk6 ZOgkX290Q92W
yTXPHnmiN+j0u+sjyA9g+BD73iLrgSlTMAeMDcNUU8/t9FQpwkbE0B1EtiQo +DC4j4vocdab
OgnVMCRuPKKIDF5IBfc59MOz7tFfh6jSH4dzdpm4e2mO2Mk0LUa0eTTtNhjq eJ3F/clsMJz9
MMcPT1gBk/HYfnz2H5U35g4gqyTww0C8F6skSmEVOlndMBWJFvkbFNI7eYTm 3fV1SbYUWmMZ
/ZzOBKAKkDV2lXRr1ZBjaeq+wFVNKhTjI3NQ2ncWXMO6Jg9GPlG5eTqTAni9 sMJ2ZkniCAyj
Q7uB6IVUg5IaV0IKw9u2g1DD27qhUD9tipFqR5hqENOjOwqBfTWt6q6suIQm j/Pr0nGZ2VUS
0K7zxcxWfJiPq6vSNRPv+nJnPbrD6l3j8tzEdWtxaWF+c390QTvY1GnX3V1l uAISP/grAHWj
kWjsV6jixFeEOhDBOahZFoNYEXdhl0QdCbhIZ6S+sPtfAGs0pX4973oFlyS4 36MxziJcyFXU
780/DhdPT/ezf0aLuQ+0i3SpJdulaZCBjk3DpQX7cNZ/NshzJl6yYQqmwRSW J6VvRrTrM7I+
zEi3a6AfQ5n0QC3u5f/+R3wA8MOobUTH2h5Q0JqZl7aJDn9WUOr3o5GzEXt6 +tR7GL42i6r2
i9AoqeYfBA1M6hazRLtOHmV5MflPXCzMjd9nsmc7R9G2tcJX0tUVWUwGE9Lb afHn2jQ8M/K2
oDcC+1zvlobqFO0S1tytNGtQNNiwi8vanL3WABKFfLRcMSO7O7qUWGCwqVEX Zh+qVlnFRhqK
MrA2Sa+HPjXT4Kz3bcsNzNZ28ZfadVugKVazk+L/40Bs8cagtn4LKuyPOkC5 T3rt6txXfwW1
bpqp4Kf9H7eu8/wsqIrOWWnt8n3scfA1Z1nSS1PfNq9FQs/P8PU/UEsHCIDc s/lTBQAATBEA
AFBLAwQUAAgACAB3tLs4AAAAAAAAAAAAAAAAPAAAAGRlbW8uZWRpdG9yL3Ny Yy9kZW1vL3By
ZXNlbnRhdGlvbi9EZW1vTWFzdGVyRGV0YWlsc1BhZ2UuamF2Ya1U32vbMBB+ TiD/w9EnpzR2
OvbUMljTX2QsLGyFPRZFvthaZclIcrIy9r/vTnKTrGV0DzXGtuTvvrv77rOL 47c9RkM4hkvb
PjpV1QEyOYZ30+n0hK/vYT5b0EvXWieCsgaEKcGGGp3PY+CF1hADPTj06DZY 5nBXKw+ts5UT
TYygABBS2qYV5lGZChoR0CmhfSQRDmmnJMxGKC1WGqEzJboYR8DGg13HxbXU qvUIy26llYTP
SqKh5eY0n0amba1kvUul0FMU1VIqH5xaddzCSayINvfJRIjBdQjtWVFst9sc U57cuqrQWAld
YKsnm9NpXodGM7qXzSRe6/xZ3OHjuWYTUEYF6hYulvOUvWk1NmhCBHDg2x7F aNgK+SAqhBIb
m7c8mz7b+WhI6a0LQM3tGu1UvrYkdD5fCENx5Q2tXoFiqajxnJHX8fH/8UtK 8Qp6q8oKg8+/
SWe13hVU9I79KLpQW0f9/RBRQYiXOwuyFoYaT94hoclqQJTJCRUapLEgefKx RSCf8BigshAs
fFemtFuYRKalwzU6NJJMNIFP5Ba6XVpy6W3iSKONOzzTy0QVHc36J4dKLbyH KxrCQniy8hUG
cp3n/gF/BjSlhydB4NdoOGid2nDFL0Jm2soHWPH1nHGJn2FJfEjynsPfL1+k zfbz6kPGMfHA
dy26LG2dwNHadi7UR/SUKKDnOBpz+gGr2U8UPkC2r2P8VAijYrn03uD2Hx1l TBQpf8fubUDJ
49lYVYJ0SFpwwfylkbrZWhn6jg5NSn+O3XPfSQIdGocN0FAdB9ic3MX3LPVT FLy4s1Y/qEBm
SPcXET2gD2LW3NMujTJ7plPsN4pVFHvkjD7Lyln6vc0bHsb1T8H/Ar/UXaUM Z7jCteg0ZeBF
AiWKweAZeL64vb/58nVxP7sdj/dy50m1J8UO5ellpvMPUEsHCL4mZJC6AgAA RgYAAFBLAwQU
AAgACAB3tLs4AAAAAAAAAAAAAAAANgAAAGRlbW8uZWRpdG9yL3NyYy9kZW1v L3ByZXNlbnRh
dGlvbi9QZWFyRGV0YWlsc1BhZ2UuamF2Ya1X32/iOBB+ZqX9HyyegsSZ7Ur3 sit01/Kjh0QL
Itz2sTJkAO86cWQ79Hqn+99vHDshCXDQVaUWEs/MN+OZz+MhZesfbAskgljS VIGGxDDDZfL1
44ePH3icSmWIVFsKa8FTDXQtFdCIGbbiScSTLR3i8517HsjEwF/m63WGcqVB 7dlKAN0zkQGd
zMqVb3bhNA7EmxrM6GF8bQgnTA8u9Wmb7xu2rsetXwwNn5Y/Ybnn8AJK02/u +0qEwmoSgoC1
r81F7aUCcH5Oa/tdnBcK9iozQ+8Vj2x+r1Kc5o/nVV94tAWj6UCiXHNzpsRV 1eXZamacbqSK
MTFDMIwLPUciX1Id49ecqYuQDyxBtMiqX1AtArWqSynFD34JvLAI/6+aR9pL S5QnxdLz1Thv
UxamtMsP/BA/5q4D5LI0Wwm+JmvBtCZzYKqSWYKGAmLsD5pUM07+sZatVPE9 M0AOvCP7gn6l
sJpWEm9ccq3c+W14DI6wOtZZq2V2XHuik37Fzb9VsL3kEVkrQL95U8C4g5J3 JGUKVzxeI03E
MRqhE3ghDWHQsZ5anvRGpg9MbXmCyr+ioNcrRQI2piYrJYpvd01Rr+eFK2mM jEvp51zqoqUa
jA/CKeehWHmFe8T47z5BCvhFH7QnHNE3KPV61KXIiwLnqUv8Ox2OwsFiMl9O Zo8OQ9/QOA/u
iUdmhzg3n4p1DM+e1qBt69ju+HQ4wRD0WvE092Hj4kZAda3j0GskJyZq1sAu B7U3Op5Mp8/3
i9u7TiUOl6Zc20ROUN9vyYQQcMvMSBXoG6d4IAkeK0zGUa5KhdLk0PvItkae g8CXwIsbOayv
/gGWIBW3mLA7qSJQoXkVEHT6fezc9G62GI4Wv3368rmGnGTxQIosTnRJH7eP Cn22B/4cp2bK
ViACZ9Ml7UcWw5d2oWoLTBJcOspKXvrSqo0UwhjDyeP9dOS2bq0atSlSlL9Y fVtMZ+mejMqg
SzZMaOiUbHclHuSuvEfnwf4fzwJkVX91lTk5NvgiNQcRooubF42PL28/yUCI QALKWzrwPes0
ZCwjEO6xT+qDSIHnWmGuE9T3YBmB6zzKR7UFMBEHne4hzC6pdHY6RaoqTCEd L/6cLJ+fH28f
RmeisiEXQdVnnCKovMy2lK5MDzLim1eH1ojRvrrgS9RuZdtdkmRCuE/PLte/ f5/tQSEpoNnL
ZRxjK1sh64AlRCYh24Pv4L0eWc6GM3KbGfnLFhLcr4GIxGB2MiLaZKsrHERc 47nG8/WOmDzh
hmOl/oagdvnZu696m+WXISbd34nnUYvtcz3kyry+JdhWS4HJVOLO05VeQsPE m1LyBi95hhRs
8GfH7l2zju1hLNeZfi/QIh05roonSYpNdLb6jqcNK4wv75Cfevz+IA92LEHK BOXcagcX7K+H
3wIH3Z/Za6qkQWuUV0eI6uDgQH3IOUtpc65AKPz7D1BLBwjjfj1fPgQAAEoO AABQSwECFAAU
AAgACAB3tLs49KWx0tAAAAB4AQAADwAAAAAAAAAAAAAAAAAAAAAAZGVtby8u Y2xhc3NwYXRo
UEsBAhQAFAAIAAgAd7S7OCorfbzkAAAAmQIAAA0AAAAAAAAAAAAAAAAADQEA AGRlbW8vLnBy
b2plY3RQSwECFAAUAAgACAB3tLs4w7mUpIwAAADwAAAAFQAAAAAAAAAAAAAA AAAsAgAAZGVt
by9idWlsZC5wcm9wZXJ0aWVzUEsBAhQAFAAIAAgAd7S7OHzcCLj1AAAApgIA ABYAAAAAAAAA
AAAAAAAA+wIAAGRlbW8vcGx1Z2luLnByb3BlcnRpZXNQSwECFAAUAAgACAB3 tLs4HoxPUtkA
AABcAQAADwAAAAAAAAAAAAAAAAA0BAAAZGVtby9wbHVnaW4ueG1sUEsBAhQA FAAIAAgAd7S7
OL0jniT7AAAAsQEAABkAAAAAAAAAAAAAAAAASgUAAGRlbW8vTUVUQS1JTkYv TUFOSUZFU1Qu
TUZQSwECFAAUAAgACAB3tLs43fFALnQBAAAYBAAAFQAAAAAAAAAAAAAAAACM BgAAZGVtby9t
b2RlbC9UZXN0LmVjb3JlUEsBAhQAFAAIAAgAd7S7OHcBE/zIAQAAlwQAABgA AAAAAAAAAAAA
AAAAQwgAAGRlbW8vbW9kZWwvVGVzdC5nZW5tb2RlbFBLAQIUABQACAAIAHe0 uzisxAxNGwEA
APYBAAAZAAAAAAAAAAAAAAAAAFEKAABkZW1vL3RleHQvZGVzY3JpcHRpb24u dHh0UEsBAhQA
FAAIAAgAd7S7OInl9hdTAQAAQAMAACAAAAAAAAAAAAAAAAAAswsAAGRlbW8u ZWRpdG9yL01F
VEEtSU5GL01BTklGRVNULk1GUEsBAhQAFAAIAAgAd7S7OOfVYFlyBAAAzw8A ADcAAAAAAAAA
AAAAAAAAVA0AAGRlbW8uZWRpdG9yL3NyYy9kZW1vL3ByZXNlbnRhdGlvbi9B cHBsZURldGFp
bHNQYWdlLmphdmFQSwECFAAUAAgACAB3tLs40PFX++coAAAq2QAAMQAAAAAA AAAAAAAAAAAr
EgAAZGVtby5lZGl0b3Ivc3JjL2RlbW8vcHJlc2VudGF0aW9uL0RlbW9FZGl0 b3IuamF2YVBL
AQIUABQACAAIAHe0uziA3LP5UwUAAEwRAAA9AAAAAAAAAAAAAAAAAHE7AABk ZW1vLmVkaXRv
ci9zcmMvZGVtby9wcmVzZW50YXRpb24vRGVtb01hc3RlckRldGFpbHNCbG9j ay5qYXZhUEsB
AhQAFAAIAAgAd7S7OL4mZJC6AgAARgYAADwAAAAAAAAAAAAAAAAAL0EAAGRl bW8uZWRpdG9y
L3NyYy9kZW1vL3ByZXNlbnRhdGlvbi9EZW1vTWFzdGVyRGV0YWlsc1BhZ2Uu amF2YVBLAQIU
ABQACAAIAHe0uzjjfj1fPgQAAEoOAAA2AAAAAAAAAAAAAAAAAFNEAABkZW1v LmVkaXRvci9z
cmMvZGVtby9wcmVzZW50YXRpb24vUGVhckRldGFpbHNQYWdlLmphdmFQSwUG AAAAAA8ADwCe
BAAA9UgAAAAA
--------------080403010306060206020904--
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328610 is a reply to message #328579] Wed, 28 May 2008 14:35 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

Boris helped me play with your sample. The problem really seems to be a
design flaw in your use of the framework. You hook up an observable to
the viewer, but what you're displaying doesn't work uniformly for all
selections the viewer can generate. So you could use this logic to
ensure that only valid selections are forwarded.


final IObservableValue sel =
ViewersObservables.observeSingleSelection(viewer);
IObservableValue selection = new ComputedValue() {
protected Object calculate()
{
return sel.getValue() instanceof Pear/*or Apple*/ ?
sel.getValue() : null;
}
};

Or it might be better to react to the actual selectionChanged method
call since that's called only when your page is applicable to that
selection...


Michael Haeberlen wrote:
> Ed,
>
> ok, I spent some time to create a demo showing the issue. (sorry, but
> you were asking for it ;-))
> In the attached zip there is a demo project with a .genmodel. You will
> have to generate model (a basket containing apples and pears), edit
> and editor code and copy the provided files from the editor project. I
> am working in a 3.3 workspace but use all databinding stuff from 3.4.
> I just added an additional page to the generated multipage editor to
> display the fruits. You will have to create a model with an apple and
> a pear in the basket and then go to the master-detail page. select the
> apple and then select the pear and you will get a NPE.
>
> Thanks for your patience,
>
> Michael
>
> Ed Merks wrote:
>> Michael,
>>
>> Comments below.
>>
>>
>> Michael Haeberlen wrote:
>>> Ed,
>>>
>>> comments below.
>>>
>>>
>>> Ed Merks wrote:
>>>> Michael,
>>>>
>>>> Comments below.
>>>>
>>>>
>>>> Michael Haeberlen wrote:
>>>>> 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:
>>>>>> Michael,
>>>>>>
>>>>>> Michael Haeberlen wrote:
>>>>>>> Ed,
>>>>>>>
>>>>>>> I'm not quite sure I understand. (actually I don't know what a
>>>>>>> "wildcard feature" is).
>>>>>> They're kind of annoying confusing things, but necessary to
>>>>>> support XML Schema-based models.
>>>>>>> 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.
>>>>> 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.
>>>> 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.
>>> I agree that it does not make too much sense. But given the fact
>>> that createObservable() gets called (by
>>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue#updateInnerObservableValue()
>>>
>>> with an EObject argument which does NOT have the given feature, the
>>> current implementation makes even less sense. Returning null as I
>>> suggested initially does not work either.
>>> But maybe I was just trying to "cure the symptoms" rather than
>>> looking for the root cause of the problem, which is that
>>> createObservable() is called with an argument that does not make sense?
>>> Here what happens before createObservable() called:
>>> The situation occurs if I change the selection in the master view.
>>> Once there is a SelectionChangedEvent,
>>> org.eclipse.jface.internal.databinding.viewers.SelectionProv iderSingleSelectionObservableValue
>>> creates and fires a ValueChangeEvent which the
>>> outerChangeListener(s) in DetailObservableValue handle (and call
>>> updateInnerObservableValue()).
>>> This is all JFace Databinding code, so is there a problem in that
>>> framework? Or am I just using the frameworks in the wrong way (which
>>> is always my first working hypothesis, you know, but I just don't
>>> see what I could do differently)?
>> Given my complete lack of experience with how to use the framework in
>> an application I'm at a loss to provide anything insightful to say.
>>>>>>>
>>>>>>> The other question is what else could I do in order to fix the
>>>>>>> problem (and still use (emf-)databinding) ?
>>>>>> 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.
>>>>> 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-d idnt-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.
>>>> 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?
>>> No, you have different detail views for each selection.
>> So I'd imagine the details view should not need to (obviously can't)
>> access features that aren't appropriate for the selection.
>>
>> Again, sorry that I don't understand the picture. Perhaps if you
>> provided a running example I'd be in a better position to try it to
>> gather insights...
>>>>
>>>> Again, I've not used the framework for any significant development
>>>> work myself, which is why it's marked as provisional API.
>>>> Hopefully in the next release I'll have an opportunity for that.
>>>>>
>>>>>>>
>>>>>>> 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(((EO bject)
>>>>>>>>> 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.ObservableListTreeCont entProvider
>>>>>>>>>> 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(((EO bject)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
>
Re: [Databinding] Problem with MasterDetail and EObjectObservableMap [message #328611 is a reply to message #328610] Wed, 28 May 2008 15:28 Go to previous message
Michael Haeberlen is currently offline Michael HaeberlenFriend
Messages: 52
Registered: July 2009
Member
Ed and Boris,

thank you a lot for your big help! This is the clearly the most appropriate solution! Sorry for bothering you so much.
I like the approach with the ComputedValue since it seems to be more according to the databinding paradigm (actually I
could not figure out quickly how to use databinding methods in selectionChanged...), and I do not experience performance
problems with it.

Thanks again,
Michael

Ed Merks wrote:
> Michael,
>
> Boris helped me play with your sample. The problem really seems to be a
> design flaw in your use of the framework. You hook up an observable to
> the viewer, but what you're displaying doesn't work uniformly for all
> selections the viewer can generate. So you could use this logic to
> ensure that only valid selections are forwarded.
>
>
> final IObservableValue sel =
> ViewersObservables.observeSingleSelection(viewer);
> IObservableValue selection = new ComputedValue() {
> protected Object calculate()
> {
> return sel.getValue() instanceof Pear/*or Apple*/ ?
> sel.getValue() : null;
> }
> };
>
> Or it might be better to react to the actual selectionChanged method
> call since that's called only when your page is applicable to that
> selection...
>
>
> Michael Haeberlen wrote:
>> Ed,
>>
>> ok, I spent some time to create a demo showing the issue. (sorry, but
>> you were asking for it ;-))
>> In the attached zip there is a demo project with a .genmodel. You will
>> have to generate model (a basket containing apples and pears), edit
>> and editor code and copy the provided files from the editor project. I
>> am working in a 3.3 workspace but use all databinding stuff from 3.4.
>> I just added an additional page to the generated multipage editor to
>> display the fruits. You will have to create a model with an apple and
>> a pear in the basket and then go to the master-detail page. select the
>> apple and then select the pear and you will get a NPE.
>>
>> Thanks for your patience,
>>
>> Michael
>>
>> Ed Merks wrote:
>>> Michael,
>>>
>>> Comments below.
>>>
>>>
>>> Michael Haeberlen wrote:
>>>> Ed,
>>>>
>>>> comments below.
>>>>
>>>>
>>>> Ed Merks wrote:
>>>>> Michael,
>>>>>
>>>>> Comments below.
>>>>>
>>>>>
>>>>> Michael Haeberlen wrote:
>>>>>> 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:
>>>>>>> Michael,
>>>>>>>
>>>>>>> Michael Haeberlen wrote:
>>>>>>>> Ed,
>>>>>>>>
>>>>>>>> I'm not quite sure I understand. (actually I don't know what a
>>>>>>>> "wildcard feature" is).
>>>>>>> They're kind of annoying confusing things, but necessary to
>>>>>>> support XML Schema-based models.
>>>>>>>> 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.
>>>>>> 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.
>>>>> 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.
>>>> I agree that it does not make too much sense. But given the fact
>>>> that createObservable() gets called (by
>>>> org.eclipse.core.internal.databinding.observable.masterdetai l.DetailObservableValue#updateInnerObservableValue()
>>>>
>>>> with an EObject argument which does NOT have the given feature, the
>>>> current implementation makes even less sense. Returning null as I
>>>> suggested initially does not work either.
>>>> But maybe I was just trying to "cure the symptoms" rather than
>>>> looking for the root cause of the problem, which is that
>>>> createObservable() is called with an argument that does not make sense?
>>>> Here what happens before createObservable() called:
>>>> The situation occurs if I change the selection in the master view.
>>>> Once there is a SelectionChangedEvent,
>>>> org.eclipse.jface.internal.databinding.viewers.SelectionProv iderSingleSelectionObservableValue
>>>> creates and fires a ValueChangeEvent which the
>>>> outerChangeListener(s) in DetailObservableValue handle (and call
>>>> updateInnerObservableValue()).
>>>> This is all JFace Databinding code, so is there a problem in that
>>>> framework? Or am I just using the frameworks in the wrong way (which
>>>> is always my first working hypothesis, you know, but I just don't
>>>> see what I could do differently)?
>>> Given my complete lack of experience with how to use the framework in
>>> an application I'm at a loss to provide anything insightful to say.
>>>>>>>>
>>>>>>>> The other question is what else could I do in order to fix the
>>>>>>>> problem (and still use (emf-)databinding) ?
>>>>>>> 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.
>>>>>> 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-d idnt-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.
>>>>> 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?
>>>> No, you have different detail views for each selection.
>>> So I'd imagine the details view should not need to (obviously can't)
>>> access features that aren't appropriate for the selection.
>>>
>>> Again, sorry that I don't understand the picture. Perhaps if you
>>> provided a running example I'd be in a better position to try it to
>>> gather insights...
>>>>>
>>>>> Again, I've not used the framework for any significant development
>>>>> work myself, which is why it's marked as provisional API.
>>>>> Hopefully in the next release I'll have an opportunity for that.
>>>>>>
>>>>>>>>
>>>>>>>> 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(((EO bject)
>>>>>>>>>> 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.ObservableListTreeCont entProvider
>>>>>>>>>>> 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(((EO bject)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
>>
Previous Topic:Retarget Actions
Next Topic:Extending the Property Sheet
Goto Forum:
  


Current Time: Sun Jul 07 03:50:05 GMT 2024

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

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

Back to the top