Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Notification of cahnges in proxy elements
Notification of cahnges in proxy elements [message #420659] Sun, 06 July 2008 21:35 Go to next message
Eclipse User
Originally posted by: balutavasile.yahoo.se

Hi.
I am working on a gmf diagram editor and I try to do the following: I have
in one model A an element 1 and in a model b an element 2. The element 1
contains a reference to the element 2 that is in the other model b. If I
change the element 2, element 1 should be notified but it does not. I
tried to register a listener (EMF Adapter) with the instance of element 2
in the model A but it does not work. If element 2 is in the same model
with element 1 it works.

So any idea how proxy changes can notify elements in other resources? I do
not mean to go through the whole resource but just to register an element
in one resource(model) to listen for changes in another element existing
in another resource(model).

Thanks for the help.
Re: Notification of cahnges in proxy elements [message #420660 is a reply to message #420659] Sun, 06 July 2008 22:12 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
Vali,

Comments below.

Vali wrote:
> Hi.
> I am working on a gmf diagram editor and I try to do the following: I
> have in one model A an element 1 and in a model b an element 2. The
> element 1 contains a reference to the element 2 that is in the other
> model b. If I change the element 2, element 1 should be notified but
> it does not.
If you change element 2, only element 2 will be notified; only if you
change element 1 itself, perhaps to refer to a different element2 will
element2 be notifiied.
> I tried to register a listener (EMF Adapter) with the instance of
> element 2 in the model A but it does not work. If element 2 is in the
> same model with element 1 it works.
I know notifications work properly, so likely there's a detail here
you've not explained.
>
> So any idea how proxy changes can notify elements in other resources?
How did proxy changes enter the picture?
> I do not mean to go through the whole resource but just to register an
> element in one resource(model) to listen for changes in another
> element existing in another resource(model).
Keep in mind that element 1 will only notify for changes made directly
to element 1's features, so if you want to know about changes made to
element 2, you'll need to listen to element 2 directly.
>
> Thanks for the help.
Probably I've not helped yet, but that's because I'm not sure what
you've done nor what you're expecting....
>
>
Re: Notification of cahnges in proxy elements [message #420665 is a reply to message #420660] Mon, 07 July 2008 09:37 Go to previous messageGo to next message
Eclipse User
Originally posted by: balutavasile.yahoo.se

I know that only the element 2 is notified if it is changed but in this
case it does not notifies all its instances. It seems like there are two
instances of element 2 one associated with model A and one associated with
model B if i change the element 2 only the instance associated with model
B is notified since element 2 resides in it. But the proxy
address/identifier is the same for both instances since it is the same
element. The strange thing is that the instance associated with model A
updates also but it does not trigger its notifications. I do not know how
this gets done.

So my element 2 is referenced from different resources but this references
are (when loaded) instances of the same type with the same content. Their
proxy address/identifier is the same but it is not the same instance that
is registered with all models. It would have helped.

The problem is when the resources referencing element 2 are loaded.
Re: Notification of cahnges in proxy elements [message #420666 is a reply to message #420665] Mon, 07 July 2008 10:10 Go to previous messageGo to next message
Eclipse User
Originally posted by: balutavasile.yahoo.se

If this is difficult to understand then what I want is to notify all the
elements that reside in different models and containing the element 2.
When I set element 2 to the respective property in the containing elements
I tried to register an Adapter with that instance of element 2. This means
I have several adapters associated with element 2 in different models. But
these adapters are not all associated with the same instance because
element 2 has on instance in each loaded model. So if I change element 2
only its instance in the model it resides is notified. Not the other
instances.

I hope you understand what I mean by instance. It is like me being in
several places at the same time but not knowing of what happened to me in
one place. I know it sounds strange but this is what i have noticed while
debugging. I am not sure how it works and if this can happen. Somewhere
should be a setting to trigger notifications for all instances having the
same proxy address.
Re: Notification of cahnges in proxy elements [message #420670 is a reply to message #420665] Mon, 07 July 2008 11:24 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
Vali,

Comments below.

Vali wrote:
> I know that only the element 2 is notified if it is changed but in
> this case it does not notifies all its instances.
Actually the adapters on element 2 are notified and I'm quite sure if
there is an adapter in the list of eAdapters, it will be notified.
> It seems like there are two instances of element 2 one associated with
> model A and one associated with model B
When model A is first loaded, there will be a proxy for element 2 and
model B won't be loaded until that proxy is resolved.
> if i change the element 2 only the instance associated with model B is
> notified since element 2 resides in it.
Indeed each instance is separate and has a separate set of adapters.
> But the proxy address/identifier is the same for both instances since
> it is the same element.
I assume that at most one is the "real" instance while there might be
many proxies to it...
> The strange thing is that the instance associated with model A updates
> also but it does not trigger its notifications.
What exactly updates? When the proxy is resolved, that produces a
notification.
> I do not know how this gets done.
When element 1 first accesses elements 2 via a getter or via getting an
object at an index in the list of values, the proxy URI for element2 is
resolved to find the "real" element 2 and that proxy is replaced by that
real value, producing a RESOLVE notification (which is much like a SET
notification).
> So my element 2 is referenced from different resources but this
> references are (when loaded) instances of the same type with the same
> content. Their proxy address/identifier is the same but it is not the
> same instance that is registered with all models. It would have helped.
>
> The problem is when the resources referencing element 2 are loaded.
I'm still not sure exactly what the problem is. Note that you could use
EcoreUtil.resolveAll to resolve all proxies right up front in stead of
on-demand as they need to be resolved.
Re: Notification of cahnges in proxy elements [message #420671 is a reply to message #420666] Mon, 07 July 2008 11:35 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------010600050708080803000306
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Vali,

Comments below.

Vali wrote:
> If this is difficult to understand then what I want is to notify all
> the elements that reside in different models and containing the
> element 2.
Since there can be unidirectional references to element 2, you won't
generally know all possible models that refer to it...
> When I set element 2 to the respective property in the containing
> elements I tried to register an Adapter with that instance of element 2.
Keep in mind then that you'll also need an adapter on element1 that's
referring to element 2 so that you can change the adapter on element 2
when element 2's proxy is replaced by the "real" element 2. Here's an
example of how one might handle such a situation:

protected void handleContainment(Notification notification)
{
switch (notification.getEventType())
{
case Notification.RESOLVE:
{
Notifier oldValue = (Notifier)notification.getOldValue();
removeAdapter(oldValue);
Notifier newValue = (Notifier)notification.getNewValue();
addAdapter(newValue);
break;
}


> This means I have several adapters associated with element 2 in
> different models. But these adapters are not all associated with the
> same instance because element 2 has on instance in each loaded model.
> So if I change element 2 only its instance in the model it resides is
> notified. Not the other instances.
I see. It's important that you keep in mind that if an element 1 adds
and adapter to element 2, that it better also include logic for dealing
with when element 1 is changed to refer to a different element 2...
>
> I hope you understand what I mean by instance. It is like me being in
> several places at the same time but not knowing of what happened to me
> in one place. I know it sounds strange but this is what i have noticed
> while debugging. I am not sure how it works and if this can happen.
> Somewhere should be a setting to trigger notifications for all
> instances having the same proxy address.
An ECrossReferenceAdapter is kind of an interesting and useful thing.
You can attach it to a resource set and it will attach itself to all
objects in the resource set and there after it will track inverses of
all unidirectional references. It also does the handling of proxies
such that if you want to get all references to a "real" object, all
proxies for t hat object will be resolved and hence you'll get an
accurate answer.

--------------010600050708080803000306
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Vali,<br>
<br>
Comments below.<br>
<br>
Vali wrote:
<blockquote
cite="mid:96ff3eed12579fe4c50c008062c643e9$1@www.eclipse.org"
type="cite">If this is difficult to understand then what I want is to
notify all the elements that reside in different models and containing
the element 2. </blockquote>
Since there can be unidirectional references to element 2, you won't
generally know all possible models that refer to it...<br>
<blockquote
cite="mid:96ff3eed12579fe4c50c008062c643e9$1@www.eclipse.org"
type="cite">When I set element 2 to the respective property in the
containing elements I tried to register an Adapter with that instance
of element 2. </blockquote>
Keep in mind then that you'll also need an adapter on element1 that's
referring to element 2 so that you can change the adapter on element 2
when element 2's proxy is replaced by the "real" element 2.
Re: Notification of cahnges in proxy elements [message #420687 is a reply to message #420671] Mon, 07 July 2008 20:31 Go to previous messageGo to next message
Eclipse User
Originally posted by: balutavasile.yahoo.se

Hi.

Interesting things you are telling me here. However I can not do what I
want. An object of element1 has a field name and a field containing a
reference to the element2 that resides in another diagram. The element2
has also a field name. What I want is that when changing the name of the
"real" element2 the name of the element1 should be set to that. This must
be done immediately without the user clicking in the diagram and in this
way triggering the getters that will resolve the proxies. The name setter
on element1 will notify all the viewers listening to it to update what the
user sees in the diagram so that part is covered.

I tried to register a ECrossReferenceAdapter to the resource set of
element1 but it does not work.

So what I need is that when changing the "real" element2's name all the
references to the "real" value should be identified and their adapters
notified. I see that ECrossReferenceAdapter has some methods for handling
crossReferences and InverseReferences(and I do not really understand what
that is), but I do not know how to use this class. Where should I hook it
and what method to override.
Re: Notification of cahnges in proxy elements [message #420689 is a reply to message #420687] Mon, 07 July 2008 20:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
Vali,

Comments below.

Vali wrote:
> Hi.
>
> Interesting things you are telling me here. However I can not do what
> I want.
I explained the basic building blocks from which you can try to achieve
whatever it is you want.
> An object of element1 has a field name and a field containing a
> reference to the element2 that resides in another diagram. The
> element2 has also a field name. What I want is that when changing the
> name of the "real" element2 the name of the element1 should be set to
> that. This must be done immediately without the user clicking in the
> diagram and in this way triggering the getters that will resolve the
> proxies.
Did you try to do the resolve all proxies thing? Did you try changing
your logic for attaching an adapter such that it responds to proxy resolves?
> The name setter on element1 will notify all the viewers listening to
> it to update what the user sees in the diagram so that part is covered.
> I tried to register a ECrossReferenceAdapter to the resource set of
> element1 but it does not work.
There should only be one resource set. What do you mean by "it does not
work"? What exactly did you try to do?
> So what I need is that when changing the "real" element2's name all
> the references to the "real" value should be identified and their
> adapters notified.
So with an ECrossReferenceAdapter, you should be able to find all the
references to element 2. The ECrossReferenceAdapter is also just an
adapter and will also see the notification that happens when element2's
field name is changed...
> I see that ECrossReferenceAdapter has some methods for handling
> crossReferences and InverseReferences(and I do not really understand
> what that is
Not understanding it and it not working are related but different issues.
> ), but I do not know how to use this class. Where should I hook it and
> what method to override.
I imagine you might specialize the ECrossReferenceAdapter to override
notifyChanged to detect when an element2's field name is changed; be
sure to call super when you override this method since handling
notification via calls to selfAdapt is important. When you detect such
a notification, you could call getInverseReferences for element2 to find
all the other objects that are referencing element2.
Re: Notification of cahnges in proxy elements [message #420692 is a reply to message #420689] Mon, 07 July 2008 21:14 Go to previous messageGo to next message
Eclipse User
Originally posted by: balutavasile.yahoo.se

Hi again Ed. Is you have noticed I an not well accustomed with emf
framework.

ED: Did you try to do the resolve all proxies thing?

No. I do not know how to do that. I have noticed that the getter for
element2 in element1 has something that does that(it is a generated
getter) but otherwise no idea where and when all proxies can be resolved.

ED: Did you try changing your logic for attaching an adapter such that it
responds to proxy resolves?

The problem is where should I attach the adapter? To element1, to whatever
instance of element 2(this is in many places) or to resource set. I have
actually tried all these but the adapter does not get notified.

ED: I imagine you might specialize the ECrossReferenceAdapter to override
notifyChanged to detect when an element2's field name is changed; be sure
to call super when you override this method since handling notification
via calls to selfAdapt is important. When you detect such a notification,
you could call getInverseReferences for element2 to find all the other
objects that are referencing element2.

Well the same problem where to attach this specialized adapter? To what
object? Should it be the resource set? Inside an item provider?
Re: Notification of cahnges in proxy elements [message #420693 is a reply to message #420692] Mon, 07 July 2008 23:28 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
Vali,

Comments below.

Vali wrote:
> Hi again Ed. Is you have noticed I an not well accustomed with emf
> framework.
>
> ED: Did you try to do the resolve all proxies thing?
> No. I do not know how to do that.
I mentioned EcoreUtil.resolveAll though...
> I have noticed that the getter for element2 in element1 has something
> that does that(it is a generated getter) but otherwise no idea where
> and when all proxies can be resolved.
They're resolve as you try to get the value the first time.
> ED: Did you try changing your logic for attaching an adapter such that
> it responds to proxy resolves?
>
> The problem is where should I attach the adapter?
I'm not sure where you're attaching them now. That's part of the
problem: I don't really know what you're going because you're not
showing me any code...
> To element1, to whatever instance of element 2(this is in many places)
> or to resource set. I have actually tried all these but the adapter
> does not get notified.
I can't know what you've tried if you don't show me...
>
> ED: I imagine you might specialize the ECrossReferenceAdapter to
> override notifyChanged to detect when an element2's field name is
> changed; be sure to call super when you override this method since
> handling notification via calls to selfAdapt is important. When you
> detect such a notification, you could call getInverseReferences for
> element2 to find all the other objects that are referencing element2.
>
> Well the same problem where to attach this specialized adapter?
You can attach it to the resource set.
> To what object? Should it be the resource set?
Yes, that way it attaches to everything contained by the resource set.
> Inside an item provider?
No. The more concrete you are about your questions, i.e., specific code
demonstrating what you are trying, the more concrete I can be with my
answers...
>
>
>
>
>
Re: Notification of cahnges in proxy elements [message #420721 is a reply to message #420693] Tue, 08 July 2008 17:03 Go to previous messageGo to next message
Eclipse User
Originally posted by: balutavasile.yahoo.se

/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void setRequirement(Requirement newRequirement) {
Requirement oldRequirement = requirement;
requirement = newRequirement;
requirement.eResource().getResourceSet().eAdapters().add(new
ECrossReferenceAdapter() {
@Override
public void notifyChanged(Notification notification) {
// TODO Auto-generated method stub
super.notifyChanged(notification);
}

});

setName(requirement.getName());
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET,
SysmlPackage.SATISFIES_PROPERTY__REQUIREMENT, oldRequirement,
requirement));
}

Well element1 is in reality a class called SatisfiedByProperty and
element2 is requirement in above code. My first idea was that when the
requirement is set to register an adapter to it here. And I am still stuck
on my idea because for the moment I can not see other alternative since I
do not have enough knowledge about the platform. Above is when I try to
attach it to the resource set of requirement.

As yo can see this code is generated from an ecore model and I have only
generated the model and edit code. The editor is generated with GMF.
The adaper is not populated since I wanted to see if it is notified if
attached in this way. It is not difficult for me to populate the adapter
but I need to find a place where to attach it. Or where to use resolve
all.
Re: Notification of cahnges in proxy elements [message #420725 is a reply to message #420721] Tue, 08 July 2008 19:16 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
Vali,

Comments below.

Vali wrote:
> /**
> * <!-- begin-user-doc -->
> * <!-- end-user-doc -->
> * @generated NOT
> */
> public void setRequirement(Requirement newRequirement) {
> Requirement oldRequirement = requirement;
> requirement = newRequirement;
> requirement.eResource().getResourceSet().eAdapters().add(new
> ECrossReferenceAdapter() {
No, you'd use just new AdapterImpl. An ECrossReferenceAdapter attaches
itself to an entire tree of objects so this code is brutal. You'd also
need to worry about removing the adapter from oldRequirement. And as we
discussed already, you'd need to worry about change the adapter from
listening to the proxy to listening to the resolved object (which
happens in the getRequirement method.
> @Override
> public void notifyChanged(Notification notification) {
> // TODO Auto-generated method stub
> super.notifyChanged(notification);
> }
>
> });
>
> setName(requirement.getName());
Is the name feature itself transient (so that it isn't serialized)? Is
the name feature derived (so that it isn't copied)?
> if (eNotificationRequired())
> eNotify(new ENotificationImpl(this, Notification.SET,
> SysmlPackage.SATISFIES_PROPERTY__REQUIREMENT, oldRequirement,
> requirement));
> }
>
> Well element1 is in reality a class called SatisfiedByProperty and
> element2 is requirement in above code. My first idea was that when the
> requirement is set to register an adapter to it here. And I am still
> stuck on my idea because for the moment I can not see other
> alternative since I do not have enough knowledge about the platform.
> Above is when I try to attach it to the resource set of requirement.
You'd need a normal adapter. You'd need to be sure to remove the
adapter from the old requirement and set it to the new requirement every
time set is called. And you'd have to ensure you do the same thing when
the proxy is resolved. Another way you might do that is attach an
adapter to the "this/element1" object itself and listen for changes to
the "requirement" feature, i.e., pay attention to SET and RESOLVE
notifications and attach the element2 adapter to the new value and also
remove it from the old value.
>
> As yo can see this code is generated from an ecore model and I have
> only generated the model and edit code. The editor is generated with
> GMF. The adaper is not populated since I wanted to see if it is
> notified if attached in this way. It is not difficult for me to
> populate the adapter but I need to find a place where to attach it. Or
> where to use resolve all.
If you want all this to happen directly in the model itself, what I'd
probably do is override eNotificationRequired to return true, so that a
notification is always produced, override eNotify (the same way as if
you'd attached an adapter to "this") to monitor notifications for the
"requirements" feature (being sure to call super), and then using
notifications on the "requirements" feature to add and remove the
adapter you attach to the requirements feature (and to copy the name
over at the time the requirements feature changes).


Something like this:

protected Adapter adapter =
new AdapterImpl()
{
public void notifyChanged(Notification notification)
{
// Pay attention to the name feature
}
};

public boolean eNotificationRequired()
{
return true;
}

public void eNotify(Notification notification)
{
if (notification.getFeature() ==
YourPackage.Literals.ELEMENT1_REQUIREMENT)
{
switch (notification.getEventType())
{
case Notification.SET:
case Notification.RESOLVE:
{
RequirementoldValue = (Requirement)notification.getOldValue();
if (oldValue != null)
{
oldValue.eAdapters().remove(adapter);
}
RequirementnewValue = (Requirement)notification.getNewValue();
if (newValue != null)
{
oldValue.eAdapters().add(adapter);
// set the name...
}
break;
}
}
}
super.eNotify(notification);
}
Re: Notification of cahnges in proxy elements [message #420727 is a reply to message #420725] Tue, 08 July 2008 20:58 Go to previous messageGo to next message
Eclipse User
Originally posted by: balutavasile.yahoo.se

Finally. It works.

Is it a standard way to attach/detach adapters in eNotify?

I did not need to override eNotificationRequired. Just overrided eNotify
in element1 and of course used an adapter.

Thanks and I hope I did not ruined your days. :)
Re: Notification of cahnges in proxy elements [message #420728 is a reply to message #420727] Tue, 08 July 2008 21:15 Go to previous message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------040800070102090506080905
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Vali,

Comments below.

Vali wrote:
> Finally. It works.
>
> Is it a standard way to attach/detach adapters in eNotify?
Part of this is just kind of a tricky way for an object to listen to its
own notifications without having to attach an adapter. If you look at
EContentAdapter, which is an adapter that maintains itself on all
objects contained in the tree and hence has to add to new ones that are
attached and remove from ones that are detached, it has much the same logic:

case Notification.SET:
{
Notifier oldValue = (Notifier)notification.getOldValue();
if (oldValue != null)
{
removeAdapter(oldValue);
}
Notifier newValue = (Notifier)notification.getNewValue();
if (newValue != null)
{
addAdapter(newValue);
}
break;
}

> I did not need to override eNotificationRequired. Just overrided
> eNotify in element1 and of course used an adapter.
Keep in mind though that eNotify is called if and only if there is an
adapter listening, so you'd be best to override it to ensure that it's
always called since you are relying on it always being called.
> Thanks and I hope I did not ruined your days. :)
No. You'll have to try harder next time. :-P
>
>
>

--------------040800070102090506080905
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Vali,<br>
<br>
Comments below.<br>
<br>
Vali wrote:
<blockquote
cite="mid:957196721955ed96808a349d7c4ff931$1@www.eclipse.org"
type="cite">Finally. It works.
<br>
<br>
Is it
Previous Topic:Problems Validation with OCL an atribute of EDataType
Next Topic:EMFT Validation and accessing OCL custom files
Goto Forum:
  


Current Time: Fri Oct 24 23:12:13 GMT 2014

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

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