Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Refreshing an object inside a resource
Refreshing an object inside a resource [message #431821] Mon, 27 July 2009 20:30 Go to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hello All,
I have a question about the proper way to do something in EMF. I have an EMF model of a tree which
I display in an SWT Tree Viewer. The model is loaded as needed (resolving proxies) and each node in
the tree is a separate resource. To handle the access to the data source, I have created my own
type of ResourceSet that knows how to load things.
Where I've gotten into trouble is when I need to refresh things from the data source (i.e. the
source's values have changed and we need to get the latest). Currently, inside my ResourceSet I
have code that does this for the refresh:

resource.unload(); // Unload the resource
demandLoadHelper(resource); // Reload the resource

That unloads all the objects that are part of the resource (one node in the tree) and reloads them
all. It works okay, except that I need to refresh the SWT viewer (to show the reloaded values).
To refresh the SWT viewer, I currently have adapters (listeners) on each node of the tree.
Unfortunately, the unload() call does not create any sort of notification except notification that
the adapter is being removed. The demandLoadHelper() loads in a whole new object, so I don't have
an adapter there yet to listen to the load. The unload() also leaves the old object in place in the
model (i.e. it does not remove it from its eContainer and the things it contains still have a
pointer to it), but marks it as "not loaded" and restores the eProxy information to it. The
demandLoadHelper() call doesn't load the new object's parent (that is still a proxy) so the SWT
viewer actually has the old "unloaded" object.
To work around this problem, I'm actually having the SWT viewer refresh the node's parent node
whenever an adapter gets removed from the EMF model. This doesn't work for the root of the tree (it
has no parent). It seems there should be a better way to go about this. W
Is there a better way to refresh/reload EMF objects? Is there a better way to get the notifications?
Thanks in advance!

--Stephen
Re: Refreshing an object inside a resource [message #431828 is a reply to message #431821] Mon, 27 July 2009 21:36 Go to previous messageGo to next message
Mario Winterer is currently offline Mario WintererFriend
Messages: 136
Registered: July 2009
Senior Member
Hi Stephen!

"Stephen McCants" <stephenmccants@yahoo.com> schrieb im Newsbeitrag
news:h4l2ns$bak$1@build.eclipse.org...
> Hello All,
> I have a question about the proper way to do something in EMF. I have an
> EMF model of a tree which I display in an SWT Tree Viewer. The model is
> loaded as needed (resolving proxies) and each node in the tree is a
> separate resource. To handle the access to the data source, I have
> created my own type of ResourceSet that knows how to load things.

I think subclassing ResourceSet is not recommended! Custom data sources
should be handled by custom implementations of Resource (see
XMLResourceImpl, XMIResourceImpl or BinaryResourceImpl for example). (If you
really need custom ResourceSet behaviour have a look how they did it in
CDO - they use some kind of adapter pattern to come around that issue.)

> Where I've gotten into trouble is when I need to refresh things from the
> data source (i.e. the source's values have changed and we need to get the
> latest). Currently, inside my ResourceSet I have code that does this for
> the refresh:
>
> resource.unload(); // Unload the resource
> demandLoadHelper(resource); // Reload the resource
>
> That unloads all the objects that are part of the resource (one node in
> the tree) and reloads them all. It works okay, except that I need to
> refresh the SWT viewer (to show the reloaded values).
> To refresh the SWT viewer, I currently have adapters (listeners) on each
> node of the tree.

For our purposes, a JFace TreeViewer with an AdapterFactoryContentProvider
and an AdapterFactoryLabelProvider works perfectly!
All content modifications automatically become visible in the viewer - no
need to register any (additional) adapters "manually".

> Unfortunately, the unload() call does not create any sort of notification
> except notification that the adapter is being removed. The
> demandLoadHelper() loads in a whole new object, so I don't have an
> adapter there yet to listen to the load. The unload() also leaves the old
> object in place in the model (i.e. it does not remove it from its
> eContainer and the things it contains still have a pointer to it), but
> marks it as "not loaded" and restores the eProxy information to it. The
> demandLoadHelper() call doesn't load the new object's parent (that is
> still a proxy) so the SWT viewer actually has the old "unloaded" object.

When a resource is unloaded or loaded, you should get at least two
notifications (on the resource):
Resource.RESOURCE__IS_LOADED and Resource.RESOURCE__CONTENTS.
Have a look at ResourceItemProvider#notifyChanged(Notification) for details.

> To work around this problem, I'm actually having the SWT viewer refresh
> the node's parent node whenever an adapter gets removed from the EMF
> model. This doesn't work for the root of the tree (it has no parent). It
> seems there should be a better way to go about this. W
> Is there a better way to refresh/reload EMF objects? Is there a better
> way to get the notifications?

For your AdapterFactoryContentProvider and AdapterFactoryLabelProvider, use
a ComposedAdapterFactory (for the content and label providers) that contains
at least your custom model's item provider adapter factory as well as the
ResourceItemProviderAdapterFactory which takes care of the ResourceSet and
the Resources (including load/unload).

> Thanks in advance!
>
> --Stephen
>

Mario
Re: Refreshing an object inside a resource [message #431885 is a reply to message #431828] Tue, 28 July 2009 16:08 Go to previous messageGo to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi Mario!

>> Hello All,
>> I have a question about the proper way to do something in EMF. I have
>> an EMF model of a tree which I display in an SWT Tree Viewer. The
>> model is loaded as needed (resolving proxies) and each node in the
>> tree is a separate resource. To handle the access to the data source,
>> I have created my own type of ResourceSet that knows how to load things.
>
> I think subclassing ResourceSet is not recommended! Custom data sources
> should be handled by custom implementations of Resource (see
> XMLResourceImpl, XMIResourceImpl or BinaryResourceImpl for example). (If
> you really need custom ResourceSet behaviour have a look how they did it
> in CDO - they use some kind of adapter pattern to come around that issue.)

I didn't describe what I've done very well (in part because I didn't remember the details myself).
I'm using a URIConverter and specialized Input and Output Streams to handle the reading and writing.
Since I'm writing and reading XMI, I use the XMIResourceImpl to turn the streams into objects. I
overrode some of the ResourceSet for two reasons:

1) To set track modifications to true on every object (inside createResource)
2) To automatically detect when our cached object is out of date and reload it (inside getResource)

I'll have to take a look at what CDO did later. Thanks for the tip.
>
> When a resource is unloaded or loaded, you should get at least two
> notifications (on the resource):
> Resource.RESOURCE__IS_LOADED and Resource.RESOURCE__CONTENTS.
> Have a look at ResourceItemProvider#notifyChanged(Notification) for
> details.

I realized one of my mistakes was listening on the object inside the resource and not the resource
itself. The resource itself sends more notification about what is going on than the object itself.
>
>> To work around this problem, I'm actually having the SWT viewer
>> refresh the node's parent node whenever an adapter gets removed from
>> the EMF model. This doesn't work for the root of the tree (it has no
>> parent). It seems there should be a better way to go about this. W
>> Is there a better way to refresh/reload EMF objects? Is there a
>> better way to get the notifications?
>
> For your AdapterFactoryContentProvider and AdapterFactoryLabelProvider,
> use a ComposedAdapterFactory (for the content and label providers) that
> contains at least your custom model's item provider adapter factory as
> well as the ResourceItemProviderAdapterFactory which takes care of the
> ResourceSet and the Resources (including load/unload).

I tried looking at that stuff and I got totally lost in AdapterFactoryAdapterFaotoryFactoryAdapter.
I'm not sure which piece of code is suppose to do what. There is a great deal of code behind
these classes and I think I'm not interested in 90% of it. For instance, I don't want to display
resources in my viewer, only their contents. Also, I saw code that directly excludes all of my
objects (ResourceItemProvider.getChildren()), because it won't return objects that have a container
that is in a different resource (that is all of my objects). Most of the code requires some vaguely
named AdapterFactory that I'm not sure what it needs to do.

In short, I'm very confused. Is there a tutorial or good explanation somewhere?

Thanks!

--Stephen
Re: Refreshing an object inside a resource [message #431888 is a reply to message #431885] Tue, 28 July 2009 16:23 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33137
Registered: July 2009
Senior Member
Stephen,

Comments below.

Stephen McCants wrote:
> Hi Mario!
>
>>> Hello All,
>>> I have a question about the proper way to do something in EMF. I
>>> have an EMF model of a tree which I display in an SWT Tree Viewer.
>>> The model is loaded as needed (resolving proxies) and each node in
>>> the tree is a separate resource. To handle the access to the data
>>> source, I have created my own type of ResourceSet that knows how to
>>> load things.
>>
>> I think subclassing ResourceSet is not recommended! Custom data
>> sources should be handled by custom implementations of Resource (see
>> XMLResourceImpl, XMIResourceImpl or BinaryResourceImpl for example).
>> (If you really need custom ResourceSet behaviour have a look how they
>> did it in CDO - they use some kind of adapter pattern to come around
>> that issue.)
>
> I didn't describe what I've done very well (in part because I didn't
> remember the details myself). I'm using a URIConverter and specialized
> Input and Output Streams to handle the reading and writing. Since I'm
> writing and reading XMI, I use the XMIResourceImpl to turn the streams
> into objects. I overrode some of the ResourceSet for two reasons:
>
> 1) To set track modifications to true on every object (inside
> createResource)
That could be done with an adapter on the resource set that detects when
a resource is added.
> 2) To automatically detect when our cached object is out of date and
> reload it (inside getResource)
Hmmm....
>
> I'll have to take a look at what CDO did later. Thanks for the tip.
>>
>> When a resource is unloaded or loaded, you should get at least two
>> notifications (on the resource):
>> Resource.RESOURCE__IS_LOADED and Resource.RESOURCE__CONTENTS.
>> Have a look at ResourceItemProvider#notifyChanged(Notification) for
>> details.
>
> I realized one of my mistakes was listening on the object inside the
> resource and not the resource itself. The resource itself sends more
> notification about what is going on than the object itself.
You might find something like an EContentAdapter useful...
>>
>>> To work around this problem, I'm actually having the SWT viewer
>>> refresh the node's parent node whenever an adapter gets removed from
>>> the EMF model. This doesn't work for the root of the tree (it has
>>> no parent). It seems there should be a better way to go about this. W
>>> Is there a better way to refresh/reload EMF objects? Is there a
>>> better way to get the notifications?
>>
>> For your AdapterFactoryContentProvider and
>> AdapterFactoryLabelProvider, use a ComposedAdapterFactory (for the
>> content and label providers) that contains at least your custom
>> model's item provider adapter factory as well as the
>> ResourceItemProviderAdapterFactory which takes care of the
>> ResourceSet and the Resources (including load/unload).
>
> I tried looking at that stuff and I got totally lost in
> AdapterFactoryAdapterFaotoryFactoryAdapter.
:-P
> I'm not sure which piece of code is suppose to do what.
Debuggers are very helpful for doing dynamic analysis...
> There is a great deal of code behind these classes and I think I'm not
> interested in 90% of it. For instance, I don't want to display
> resources in my viewer, only their contents.
Just like the generated editors do...
> Also, I saw code that directly excludes all of my objects
> (ResourceItemProvider.getChildren()), because it won't return objects
> that have a container that is in a different resource (that is all of
> my objects). Most of the code requires some vaguely named
> AdapterFactory that I'm not sure what it needs to do.
>
> In short, I'm very confused. Is there a tutorial or good explanation
> somewhere?
Read the introductory article for the EMF Edit framework. The EMF book
has all the gory details...
>
> Thanks!
>
> --Stephen


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:Limited List
Next Topic:Importing ecore model - errors with validation and conversion - How to debug?
Goto Forum:
  


Current Time: Sat Apr 20 03:56:35 GMT 2024

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

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

Back to the top