Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » AddCommand not updating Resource using TransactionalEditingDomain
AddCommand not updating Resource using TransactionalEditingDomain [message #422279] Thu, 28 August 2008 12:33 Go to next message
Tor Neple is currently offline Tor NepleFriend
Messages: 57
Registered: July 2009
Member
Hello

Context: Based on a EMF model we generated the usual parts, then (to the
best of our ability, based on the tutorial, examples and newsgroup)
altered the generated Editor to support the use of EMF Transactions. We
then created yet another plugin that provides an API toward the model in
addition to actions in the UI. This other plugin also uses EMF
Transactions, and we share the editing-domain with the generated/altered
Editor.

Then to the issue. We have an UI action (in the other plugin) that is to
add an element to the model that is shown in the current Editor. The
first time (after startup) this action is run it works fine, subsequent
runs do not work. I have debugged this issue in detail, and have found
some strange behaviour related to where we actually perform the adding
of the element to the model. The following code:

private void executeAddCommand(EObject e){
System.out.println("Domain: count before add:
"+_traceModel.eContents().size());
System.out.println("Domain count before add:
"+_resource.getContents().get(0).eContents().size());
Command cmd = AddCommand.create(_traceEditingDomain,
getTraceModel(), null, e);
TransactionalCommandStack trStack =
(TransactionalCommandStack)_traceEditingDomain.getCommandSta ck();
try
{
trStack.execute(cmd, Collections.EMPTY_MAP);
System.out.println("Domain: count after add:
"+_traceModel.eContents().size());
System.out.println("Domain count after add:
"+_resource.getContents().get(0).eContents().size());
}
catch (Exception ex)
{
ex.printStackTrace();
}
}


The strange thing is that if the number of elements in the _traceModel
is 5 and in the _resource are 5 before the AddCommand is done, after the
add the count in the _traceModel is 6, but the number in the _resource
is still 5. So, either I have got the concept of the Transactions
totally wrong, or there is some small detail that I have missed. Anly
clews? It is probably hard to answer this based on only this
information, but the problem may be symptomatic.

BTW; in this scenario should I implement listeners for the transaction
stack and the resource(set) in both plugins? I guess a reload of the
model is needed in plugin1 if it has been changed in Plugin2? Or should
this now be automatical through the use of the TransactionalEditingDomain?


Thanks in advance for any hints.

Regards

Tor Neple
Re: AddCommand not updating Resource using TransactionalEditingDomain [message #422283 is a reply to message #422279] Thu, 28 August 2008 12:59 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: cdamus.zeligsoft.com

Hi, Tor,

See some replies in-line, below.

HTH,

Christian

Tor Neple wrote:
> Hello
>
> Context: Based on a EMF model we generated the usual parts, then (to the
> best of our ability, based on the tutorial, examples and newsgroup)
> altered the generated Editor to support the use of EMF Transactions. We
> then created yet another plugin that provides an API toward the model in
> addition to actions in the UI. This other plugin also uses EMF
> Transactions, and we share the editing-domain with the generated/altered
> Editor.

Yes, this is a classic use case for transactions. You may also be
interested in this: https://bugs.eclipse.org/211524


> Then to the issue. We have an UI action (in the other plugin) that is to
> add an element to the model that is shown in the current Editor. The
> first time (after startup) this action is run it works fine, subsequent
> runs do not work. I have debugged this issue in detail, and have found
> some strange behaviour related to where we actually perform the adding
> of the element to the model. The following code:
>
> private void executeAddCommand(EObject e){
> System.out.println("Domain: count before add:
> "+_traceModel.eContents().size());
> System.out.println("Domain count before add:
> "+_resource.getContents().get(0).eContents().size());
> Command cmd = AddCommand.create(_traceEditingDomain,
> getTraceModel(), null, e);
> TransactionalCommandStack trStack =
> (TransactionalCommandStack)_traceEditingDomain.getCommandSta ck();
> try
> {
> trStack.execute(cmd, Collections.EMPTY_MAP);
> System.out.println("Domain: count after add:
> "+_traceModel.eContents().size());
> System.out.println("Domain count after add:
> "+_resource.getContents().get(0).eContents().size());
> }
> catch (Exception ex)
> {
> ex.printStackTrace();
> }
> }
>
>
> The strange thing is that if the number of elements in the _traceModel
> is 5 and in the _resource are 5 before the AddCommand is done, after the
> add the count in the _traceModel is 6, but the number in the _resource
> is still 5. So, either I have got the concept of the Transactions
> totally wrong, or there is some small detail that I have missed. Anly
> clews? It is probably hard to answer this based on only this
> information, but the problem may be symptomatic.

It would seem that you are expecting _tracemodel and the first element
in _resource to be identical objects? Clearly, they are not, because
they have a different number of contained objects.

I'm afraid I will need to know more about what the relationship between
_tracemodel and _resource.getContents().get(0) is supposed to be, in
order to provide any useful help. Also, nothing here suggests that this
is a transaction-related problem. If you do the same in a
non-transactional editing domain (just an AdapterFactoryEditingDomain),
then what do you see?


> BTW; in this scenario should I implement listeners for the transaction
> stack and the resource(set) in both plugins? I guess a reload of the
> model is needed in plugin1 if it has been changed in Plugin2? Or should
> this now be automatical through the use of the TransactionalEditingDomain?

I have no idea whether listeners would help, because I don't know what
your code is trying to do or what the structure of your data looks like.
Are you employing listeners, already, to maintain consistency of the
_tracemodel and the _resource? If so, then perhaps the problem is in there.

In any case, reloading only restores a resource's contents from the
persisted state. I don't expect that you'd be wanting to do any of
that, here. The transactional editing domain helps to coordinate
changes in resources shared amongst multiple editors in memory, not on disk.


> Thanks in advance for any hints.
>
> Regards
>
> Tor Neple
Re: AddCommand not updating Resource using TransactionalEditingDomain [message #422286 is a reply to message #422283] Thu, 28 August 2008 13:46 Go to previous messageGo to next message
Tor Neple is currently offline Tor NepleFriend
Messages: 57
Registered: July 2009
Member
Thanks for the swift reply Christian, meta-replies (replies to replies)
and more questions/clarifications inline below.

Regards

Tor
Christian W. Damus wrote:
> Hi, Tor,
>
> See some replies in-line, below.
>
> HTH,
>
> Christian
>
> Tor Neple wrote:
>> Hello
>>
>> Context: Based on a EMF model we generated the usual parts, then (to
>> the best of our ability, based on the tutorial, examples and
>> newsgroup) altered the generated Editor to support the use of EMF
>> Transactions. We then created yet another plugin that provides an API
>> toward the model in addition to actions in the UI. This other plugin
>> also uses EMF Transactions, and we share the editing-domain with the
>> generated/altered Editor.
>
> Yes, this is a classic use case for transactions. You may also be
> interested in this: https://bugs.eclipse.org/211524

Yes, that feature would save a lot of work. And it should assure that it
gets right, so people like me don't clutter things up to badly ;-)
>
>
>> Then to the issue. We have an UI action (in the other plugin) that is
>> to add an element to the model that is shown in the current Editor.
>> The first time (after startup) this action is run it works fine,
>> subsequent runs do not work. I have debugged this issue in detail, and
>> have found some strange behaviour related to where we actually perform
>> the adding of the element to the model. The following code:
>>
>> private void executeAddCommand(EObject e){
>> System.out.println("Domain: count before add:
>> "+_traceModel.eContents().size());
>> System.out.println("Domain count before add:
>> "+_resource.getContents().get(0).eContents().size());
>> Command cmd = AddCommand.create(_traceEditingDomain,
>> getTraceModel(), null, e);
>> TransactionalCommandStack trStack =
>> (TransactionalCommandStack)_traceEditingDomain.getCommandSta ck();
>> try
>> {
>> trStack.execute(cmd, Collections.EMPTY_MAP);
>> System.out.println("Domain: count after add:
>> "+_traceModel.eContents().size());
>> System.out.println("Domain count after add:
>> "+_resource.getContents().get(0).eContents().size());
>> }
>> catch (Exception ex)
>> {
>> ex.printStackTrace();
>> }
>> }
>>
>>
>> The strange thing is that if the number of elements in the _traceModel
>> is 5 and in the _resource are 5 before the AddCommand is done, after
>> the add the count in the _traceModel is 6, but the number in the
>> _resource is still 5. So, either I have got the concept of the
>> Transactions totally wrong, or there is some small detail that I have
>> missed. Anly clews? It is probably hard to answer this based on only
>> this information, but the problem may be symptomatic.
>
> It would seem that you are expecting _tracemodel and the first element
> in _resource to be identical objects? Clearly, they are not, because
> they have a different number of contained objects.

Ok. the _resource contains the resource that I have obtained from the
TransactionalEditingDomain. The _tracemodel is the model that is stored
in the _resource, so I guess logically these should be the same thing,
but as you say they cannot be. Let me check the actual objects
returned...I altered the output from the code above to show the acutal
object and I got the following:

_tracemodel count before add: 9
_resource contents count before add: 9

_tracemodel contents before add:
org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1a5342b (eProxyURI:
platform:/resource/TramdeTests/My.tramdemodel#/)

_resource contents before add:
org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1523ccf (id: null)
(name: testmodel)

_tracemodel count after add: 10
_resource contents count after add: 9

_tracemodel contents add:
org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1a5342b (eProxyURI:
platform:/resource/TramdeTests/My.tramdemodel#/)

_resource contents after add:
org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1523ccf (id: null)
(name: testmodel)

So it seems that the AddCommand alters my _tracemodel, but this is now
just a proxy object (not the same object at all), and the tracemodel in
the _resource has not been updated. So, I guess somewhere along the line
_tracemodel became a proxy, what code could do that? a _resource.unload?
I guess it must be somewhere in Plugin1, because if I only run plugin2
this does not happen. So should I be looking for unloads? And what is
the correct procedure for "non-proxifying" my model?

>
> I'm afraid I will need to know more about what the relationship between
> _tracemodel and _resource.getContents().get(0) is supposed to be, in
> order to provide any useful help. Also, nothing here suggests that this
> is a transaction-related problem. If you do the same in a
> non-transactional editing domain (just an AdapterFactoryEditingDomain),
> then what do you see?
>
>
>> BTW; in this scenario should I implement listeners for the transaction
>> stack and the resource(set) in both plugins? I guess a reload of the
>> model is needed in plugin1 if it has been changed in Plugin2? Or
>> should this now be automatical through the use of the
>> TransactionalEditingDomain?
>
> I have no idea whether listeners would help, because I don't know what
> your code is trying to do or what the structure of your data looks like.
> Are you employing listeners, already, to maintain consistency of the
> _tracemodel and the _resource? If so, then perhaps the problem is in there.
>
I have a commandstack and resource listeners in the generated/altered
editor, and I experimented with a resource listener in plugin2, but
only ended up reacting to the save that was done by plugin2 (the delta
just came up with a type of ROOT) anyways...
> In any case, reloading only restores a resource's contents from the
> persisted state. I don't expect that you'd be wanting to do any of that,
> here. The transactional editing domain helps to coordinate changes in
> resources shared amongst multiple editors in memory, not on disk.
>
So if plugin1 (the generated/altered Editor) adds an element, and the
user presses "save", plugin2 needs to react to this; I clearly need to
get the model from the resource at least?
>
>> Thanks in advance for any hints.
>>
>> Regards
>>
>> Tor Neple
Re: AddCommand not updating Resource using TransactionalEditingDomain [message #422287 is a reply to message #422286] Thu, 28 August 2008 14:59 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: cdamus.zeligsoft.com

Hi, Tor,

More replies in-line.

Cheers,

Christian

Tor Neple wrote:
> Thanks for the swift reply Christian, meta-replies (replies to replies)
> and more questions/clarifications inline below.
>
> Regards
>
> Tor
> Christian W. Damus wrote:

-----8<-----


>> It would seem that you are expecting _tracemodel and the first element
>> in _resource to be identical objects? Clearly, they are not, because
>> they have a different number of contained objects.
>
> Ok. the _resource contains the resource that I have obtained from the
> TransactionalEditingDomain. The _tracemodel is the model that is stored
> in the _resource, so I guess logically these should be the same thing,
> but as you say they cannot be. Let me check the actual objects
> returned...I altered the output from the code above to show the acutal
> object and I got the following:
>
> _tracemodel count before add: 9
> _resource contents count before add: 9
>
> _tracemodel contents before add:
> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1a5342b (eProxyURI:
> platform:/resource/TramdeTests/My.tramdemodel#/)
>
> _resource contents before add:
> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1523ccf (id: null)
> (name: testmodel)
>
> _tracemodel count after add: 10
> _resource contents count after add: 9
>
> _tracemodel contents add:
> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1a5342b (eProxyURI:
> platform:/resource/TramdeTests/My.tramdemodel#/)
>
> _resource contents after add:
> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1523ccf (id: null)
> (name: testmodel)
>
> So it seems that the AddCommand alters my _tracemodel, but this is now
> just a proxy object (not the same object at all), and the tracemodel in
> the _resource has not been updated. So, I guess somewhere along the line
> _tracemodel became a proxy, what code could do that? a _resource.unload?

Exactly. Somewhere along the line, the trace model was unloaded, and
the command is continuing to update it. However, your application also
loded the resource again, so that you now have a distinct copy of the
trace model in the _resource, which is not being updated because the old
copy is still being updated.

Once an object has been unloaded (and, hence, turned into a proxy, EMF
will never use that same object again, either when resolving the proxy
or re-loading the resource that had contained it. Any variables in
which your application tores objects must forget them when they are
unloaded, and find the new copy when the resource is loaded again.


> I guess it must be somewhere in Plugin1, because if I only run plugin2
> this does not happen. So should I be looking for unloads? And what is
> the correct procedure for "non-proxifying" my model?

Yes, you should investigate why the resource is being unloaded. It
probably shouldn't be, especially as it's being loaded again immediately.

The corect procedure for un-proxifying is, as I mentioned above, to
forget all of the proxies, load the resource, and find the new copies of
the objects.


>>
>> I'm afraid I will need to know more about what the relationship between
>> _tracemodel and _resource.getContents().get(0) is supposed to be, in
>> order to provide any useful help. Also, nothing here suggests that this
>> is a transaction-related problem. If you do the same in a
>> non-transactional editing domain (just an AdapterFactoryEditingDomain),
>> then what do you see?
>>
>>
>>> BTW; in this scenario should I implement listeners for the transaction
>>> stack and the resource(set) in both plugins? I guess a reload of the
>>> model is needed in plugin1 if it has been changed in Plugin2? Or
>>> should this now be automatical through the use of the
>>> TransactionalEditingDomain?
>>
>> I have no idea whether listeners would help, because I don't know what
>> your code is trying to do or what the structure of your data looks like.
>> Are you employing listeners, already, to maintain consistency of the
>> _tracemodel and the _resource? If so, then perhaps the problem is in
>> there.
>>
> I have a commandstack and resource listeners in the generated/altered
> editor, and I experimented with a resource listener in plugin2, but
> only ended up reacting to the save that was done by plugin2 (the delta
> just came up with a type of ROOT) anyways...

Perhaps one of these is unloading the resource. It may be that your one
editor thinks that the save performed by the other editor is an
"external change" and unloads the resource and re-loads it to pick up
the changes? It should have some way to realize that an editor in the
same editing domain did the save, so that this isn't necessary.


>> In any case, reloading only restores a resource's contents from the
>> persisted state. I don't expect that you'd be wanting to do any of that,
>> here. The transactional editing domain helps to coordinate changes in
>> resources shared amongst multiple editors in memory, not on disk.
>>
> So if plugin1 (the generated/altered Editor) adds an element, and the
> user presses "save", plugin2 needs to react to this; I clearly need to
> get the model from the resource at least?

No, it should not react because the editors are sharing the resource in
the same editing domain. I think this is the crux of your problem.

>>
>>> Thanks in advance for any hints.
>>>
>>> Regards
>>>
>>> Tor Neple
>
Re: AddCommand not updating Resource using TransactionalEditingDomain [message #422301 is a reply to message #422287] Fri, 29 August 2008 08:05 Go to previous message
Tor Neple is currently offline Tor NepleFriend
Messages: 57
Registered: July 2009
Member
Thanks a million Christian !

Reloading the model from the resource before the execution of the
AddCommand made it all work! I now reload every time before the add, I
guess I can add some smartness to only reload if the model has become a
proxy...but nevertheless: thanks !


Tor

Christian W. Damus wrote:
>
> Hi, Tor,
>
> More replies in-line.
>
> Cheers,
>
> Christian
>
> Tor Neple wrote:
>> Thanks for the swift reply Christian, meta-replies (replies to
>> replies) and more questions/clarifications inline below.
>>
>> Regards
>>
>> Tor
>> Christian W. Damus wrote:
>
> -----8<-----
>
>
>>> It would seem that you are expecting _tracemodel and the first element
>>> in _resource to be identical objects? Clearly, they are not, because
>>> they have a different number of contained objects.
>>
>> Ok. the _resource contains the resource that I have obtained from the
>> TransactionalEditingDomain. The _tracemodel is the model that is
>> stored in the _resource, so I guess logically these should be the same
>> thing, but as you say they cannot be. Let me check the actual objects
>> returned...I altered the output from the code above to show the acutal
>> object and I got the following:
>>
>> _tracemodel count before add: 9
>> _resource contents count before add: 9
>>
>> _tracemodel contents before add:
>> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1a5342b (eProxyURI:
>> platform:/resource/TramdeTests/My.tramdemodel#/)
>>
>> _resource contents before add:
>> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1523ccf (id: null)
>> (name: testmodel)
>>
>> _tracemodel count after add: 10
>> _resource contents count after add: 9
>>
>> _tracemodel contents add:
>> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1a5342b (eProxyURI:
>> platform:/resource/TramdeTests/My.tramdemodel#/)
>>
>> _resource contents after add:
>> org.sintef.tramde.tramdeModel.impl.TraceModelImpl@1523ccf (id: null)
>> (name: testmodel)
>>
>> So it seems that the AddCommand alters my _tracemodel, but this is now
>> just a proxy object (not the same object at all), and the tracemodel
>> in the _resource has not been updated. So, I guess somewhere along the
>> line _tracemodel became a proxy, what code could do that? a
>> _resource.unload?
>
> Exactly. Somewhere along the line, the trace model was unloaded, and the
> command is continuing to update it. However, your application also loded
> the resource again, so that you now have a distinct copy of the trace
> model in the _resource, which is not being updated because the old copy
> is still being updated.
>
> Once an object has been unloaded (and, hence, turned into a proxy, EMF
> will never use that same object again, either when resolving the proxy
> or re-loading the resource that had contained it. Any variables in which
> your application tores objects must forget them when they are unloaded,
> and find the new copy when the resource is loaded again.
>
>
>> I guess it must be somewhere in Plugin1, because if I only run plugin2
>> this does not happen. So should I be looking for unloads? And what is
>> the correct procedure for "non-proxifying" my model?
>
> Yes, you should investigate why the resource is being unloaded. It
> probably shouldn't be, especially as it's being loaded again immediately.
>
> The corect procedure for un-proxifying is, as I mentioned above, to
> forget all of the proxies, load the resource, and find the new copies of
> the objects.
>
>
>>>
>>> I'm afraid I will need to know more about what the relationship between
>>> _tracemodel and _resource.getContents().get(0) is supposed to be, in
>>> order to provide any useful help. Also, nothing here suggests that this
>>> is a transaction-related problem. If you do the same in a
>>> non-transactional editing domain (just an AdapterFactoryEditingDomain),
>>> then what do you see?
>>>
>>>
>>>> BTW; in this scenario should I implement listeners for the transaction
>>>> stack and the resource(set) in both plugins? I guess a reload of the
>>>> model is needed in plugin1 if it has been changed in Plugin2? Or
>>>> should this now be automatical through the use of the
>>>> TransactionalEditingDomain?
>>>
>>> I have no idea whether listeners would help, because I don't know what
>>> your code is trying to do or what the structure of your data looks like.
>>> Are you employing listeners, already, to maintain consistency of the
>>> _tracemodel and the _resource? If so, then perhaps the problem is in
>>> there.
>>>
>> I have a commandstack and resource listeners in the generated/altered
>> editor, and I experimented with a resource listener in plugin2, but
>> only ended up reacting to the save that was done by plugin2 (the delta
>> just came up with a type of ROOT) anyways...
>
> Perhaps one of these is unloading the resource. It may be that your one
> editor thinks that the save performed by the other editor is an
> "external change" and unloads the resource and re-loads it to pick up
> the changes? It should have some way to realize that an editor in the
> same editing domain did the save, so that this isn't necessary.
>
>
>>> In any case, reloading only restores a resource's contents from the
>>> persisted state. I don't expect that you'd be wanting to do any of that,
>>> here. The transactional editing domain helps to coordinate changes in
>>> resources shared amongst multiple editors in memory, not on disk.
>>>
>> So if plugin1 (the generated/altered Editor) adds an element, and the
>> user presses "save", plugin2 needs to react to this; I clearly need to
>> get the model from the resource at least?
>
> No, it should not react because the editors are sharing the resource in
> the same editing domain. I think this is the crux of your problem.
>
>>>
>>>> Thanks in advance for any hints.
>>>>
>>>> Regards
>>>>
>>>> Tor Neple
>>
Previous Topic:Invalid entry feature 'XMLTypeDocumentRoot.text'
Next Topic:Bugzilla 216983
Goto Forum:
  


Current Time: Wed Apr 24 14:43:20 GMT 2024

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

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

Back to the top