Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Tracking the modification of a resource given by it’s URI
Tracking the modification of a resource given by it’s URI [message #427081] Sat, 31 January 2009 10:04 Go to next message
Zoltan Balogh is currently offline Zoltan BaloghFriend
Messages: 9
Registered: July 2009
Junior Member
Hi Group,

I have an interesting problem and I need your advice!

I have my method which has to be called twice for a given resource by
giving the URI of it. The first time I get the resource using the URI
and make some modifications. The second time (it can be so much later) I
have to be sure that the resource I’m getting this time is not different
from the first one and according to this I will do something or not.

It can be easy if I could assume that the resource is saved and
persisted when I get it the second time, because in this case I can use
the timeStamp to decide. Note that a mistake is allowed in one way,
therefore I can tell that a resource was modified even if it’s not but
not vice-versa. E.g. using the timeStamp it can happens that resource
contains the same information with a bigger timestamp but a resource
with the same timestamp has surely the same content.

The problem is that I cannot assume the saving so the changes can be
only "in the memory". In this case I could use listeners to track the
modifications but it can also be happened that the in-memory resource
is removed (e.g. by closing the editor) and there will be an other
in-memory resource instantiated for the given URI where the changes will
happen, so my listener will no longer listen. But second time I ask for
a resource with the URI I will get the modified one without no
notification from my listener.

Of course a brute force solution could be to save the content of the
resource when my method is called at first time and then compares it
whit actual resource what I see at second time call. But I can’t afford
it because of it’s high cost.

Note: I’m using Transactional Editing Domain.


Thanks for any advice!
Re: Tracking the modification of a resource given by it’s URI [message #427085 is a reply to message #427081] Sat, 31 January 2009 13:06 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33141
Registered: July 2009
Senior Member
Zoltan,

Comments below.

Zoltan Balogh wrote:
> Hi Group,
>
> I have an interesting problem and I need your advice!
>
> I have my method which has to be called twice for a given resource by
> giving the URI of it. The first time I get the resource using the URI
> and make some modifications.
So you have a resource set and call getResource(uri, true) and then make
changes to the resource.getContents() or some object below it...
> The second time (it can be so much later) I have to be sure that the
> resource I’m getting this time is not different from the first one and
> according to this I will do something or not.
Is it the same resource set? You can use setTrackingModification maybe...
>
> It can be easy if I could assume that the resource is saved and
> persisted when I get it the second time, because in this case I can
> use the timeStamp to decide.
Of course it's even possible for another application to change the
underlying resource in the file system...
> Note that a mistake is allowed in one way, therefore I can tell that a
> resource was modified even if it’s not but not vice-versa. E.g. using
> the timeStamp it can happens that resource contains the same
> information with a bigger timestamp but a resource with the same
> timestamp has surely the same content.
There's this option that saves a resource but only if the bytes are
different from the on-disk bytes.
/**
* A save option that can be used only with {@link #save(Map)}
* to specify that the resource is to be saved only if the new contents
* are different from actual contents;
* this compares the bytes in the backing store against the new bytes
that would be saved.
* The value on this option can be either <code>null</code>,
* {@link #OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER},
* or {@link #OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER}.
* @since 2.3
*/
String OPTION_SAVE_ONLY_IF_CHANGED = "SAVE_ONLY_IF_CHANGED";
>
> The problem is that I cannot assume the saving so the changes can be
> only "in the memory". In this case I could use listeners to track the
> modifications but it can also be happened that the in-memory resource
> is removed (e.g. by closing the editor) and there will be an other
> in-memory resource instantiated for the given URI where the changes
> will happen, so my listener will no longer listen.
There could be an arbitrary number of such in-memory copies; one per
resource set...
> But second time I ask for a resource with the URI I will get the
> modified one without no notification from my listener.
In any particular resource set you'll either get a new demand loaded one
of the one that's been there for a while...
>
>
> Of course a brute force solution could be to save the content of the
> resource when my method is called at first time and then compares it
> whit actual resource what I see at second time call. But I can’t
> afford it because of it’s high cost.
All in all, I don't really quite understand the context of your question...
>
> Note: I’m using Transactional Editing Domain.
>
>
> Thanks for any advice!


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Tracking the modification of a resource given by it’s URI [message #427089 is a reply to message #427085] Sat, 31 January 2009 19:03 Go to previous messageGo to next message
Zoltan Balogh is currently offline Zoltan BaloghFriend
Messages: 9
Registered: July 2009
Junior Member
Ed,

comments below.

Ed Merks wrote:
> Zoltan,
>
> Comments below.
>
> Zoltan Balogh wrote:
>> Hi Group,
>>
>> I have an interesting problem and I need your advice!
>>
>> I have my method which has to be called twice for a given resource by
>> giving the URI of it. The first time I get the resource using the URI
>> and make some modifications.
> So you have a resource set and call getResource(uri, true) and then make
> changes to the resource.getContents() or some object below it...
We have a mechanism to get a resourceSet for a given URI (let it be
"myUri").

ResourceSet myResourceSet = MyResourceSetProvider.getResourceSet(myUri);
Resource myResource = myResourceSet.getResource(myUri, true);
// make chages to the myResource.getContents() or some object below it;
>> The second time (it can be so much later) I have to be sure that the
>> resource I’m getting this time is not different from the first one and
>> according to this I will do something or not.
> Is it the same resource set? You can use setTrackingModification maybe...
Second time I also get the resorceSet with the same URI.
ResourceSet myResourceSet2= MyResourceSetProvider.getResourceSet(myUri);

But unfortunately it's not guaranteed that it is the same resourceSet.
For example if there is no in-memory resourceSet for myUri, there will
be a new one created.
>>
>> It can be easy if I could assume that the resource is saved and
>> persisted when I get it the second time, because in this case I can
>> use the timeStamp to decide.
> Of course it's even possible for another application to change the
> underlying resource in the file system...
>> Note that a mistake is allowed in one way, therefore I can tell that a
>> resource was modified even if it’s not but not vice-versa. E.g. using
>> the timeStamp it can happens that resource contains the same
>> information with a bigger timestamp but a resource with the same
>> timestamp has surely the same content.
> There's this option that saves a resource but only if the bytes are
> different from the on-disk bytes.
> /**
> * A save option that can be used only with {@link #save(Map)}
> * to specify that the resource is to be saved only if the new contents
> * are different from actual contents;
> * this compares the bytes in the backing store against the new bytes
> that would be saved.
> * The value on this option can be either <code>null</code>,
> * {@link #OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER},
> * or {@link #OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER}.
> * @since 2.3
> */ String OPTION_SAVE_ONLY_IF_CHANGED = "SAVE_ONLY_IF_CHANGED";
Thanks, this saving option is better to me.
>>
>> The problem is that I cannot assume the saving so the changes can be
>> only "in the memory". In this case I could use listeners to track the
>> modifications but it can also be happened that the in-memory resource
>> is removed (e.g. by closing the editor) and there will be an other
>> in-memory resource instantiated for the given URI where the changes
>> will happen, so my listener will no longer listen.
> There could be an arbitrary number of such in-memory copies; one per
> resource set...
Yes, but I only have to deal with the resourceSet that is created for myURI.
>> But second time I ask for a resource with the URI I will get the
>> modified one without no notification from my listener.
> In any particular resource set you'll either get a new demand loaded one
> of the one that's been there for a while...
The provider ensures that for myUri there can be only one in-memory
resourceSet and I have to deal with only the myUri's resource from it.
>>
>>
>> Of course a brute force solution could be to save the content of the
>> resource when my method is called at first time and then compares it
>> whit actual resource what I see at second time call. But I can’t
>> afford it because of it’s high cost.
> All in all, I don't really quite understand the context of your question...
I’ve thought it would be better to hide the concrete context, but maybe
it could help to demonstrate the problem:

I Would like to make a workspace scoped refactoring for my EMF models
(i.e. renaming an element will not update only the references in the
same resourceSet, but the references of other ones involved.) For
example let's "a.xml" has references to "b.xml".

ResourceSet rs1 = MyResourceSetProvider.getResourceSet("a.xml");
ResourceSet rs2 = MyResourceSetProvider.getResourceSet("b.xml");

If I rename something in b.xml working with "rs2", the refactoring will
get "rs1" for a.xml and update the needed references.

The problem is with the undo. When the undo of renaming is executed I
have to check whether the actual state of the resources of a.xml and
b.xml were modified from the time of renaming or not. Calling the undo
for a modified resource could cause erroneous behavior. In normal case
this kind of checking is not needed because the consistency of the model
is guaranteed by the command stack (an undo of a command can only be
visible if the state of the model is the same as after the execution of
the command). But as there is more than one resourceSet is involved, the
undo of the refactoring can be visible (so can invoked) even if some of
the involved resources have already been modified (unless if I could
spot these situations somehow and the difficulty of this spotting, is my
problem :).

I hope it makes clearer the problem!
>>
>> Note: I’m using Transactional Editing Domain.
>>
>>
>> Thanks for any advice!
Re: Tracking the modification of a resource given by it’s URI [message #427090 is a reply to message #427089] Sat, 31 January 2009 20:09 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33141
Registered: July 2009
Senior Member
Zoltan,

I'm really not sure what to suggest. Things like modification tracking
seem like it ought to address your issue. You can know if the resource
is modified in some way. Things like an ChangeRecorder attached to the
resource would serve a similar purpose...


Zoltan Balogh wrote:
> Ed,
>
> comments below.
>
> Ed Merks wrote:
>> Zoltan,
>>
>> Comments below.
>>
>> Zoltan Balogh wrote:
>>> Hi Group,
>>>
>>> I have an interesting problem and I need your advice!
>>>
>>> I have my method which has to be called twice for a given resource
>>> by giving the URI of it. The first time I get the resource using the
>>> URI and make some modifications.
>> So you have a resource set and call getResource(uri, true) and then
>> make changes to the resource.getContents() or some object below it...
> We have a mechanism to get a resourceSet for a given URI (let it be
> "myUri").
>
> ResourceSet myResourceSet = MyResourceSetProvider.getResourceSet(myUri);
> Resource myResource = myResourceSet.getResource(myUri, true);
> // make chages to the myResource.getContents() or some object below it;
>>> The second time (it can be so much later) I have to be sure that the
>>> resource I’m getting this time is not different from the first one
>>> and according to this I will do something or not.
>> Is it the same resource set? You can use setTrackingModification
>> maybe...
> Second time I also get the resorceSet with the same URI.
> ResourceSet myResourceSet2= MyResourceSetProvider.getResourceSet(myUri);
>
> But unfortunately it's not guaranteed that it is the same resourceSet.
> For example if there is no in-memory resourceSet for myUri, there will
> be a new one created.
>>>
>>> It can be easy if I could assume that the resource is saved and
>>> persisted when I get it the second time, because in this case I can
>>> use the timeStamp to decide.
>> Of course it's even possible for another application to change the
>> underlying resource in the file system...
>>> Note that a mistake is allowed in one way, therefore I can tell that
>>> a resource was modified even if it’s not but not vice-versa. E.g.
>>> using the timeStamp it can happens that resource contains the same
>>> information with a bigger timestamp but a resource with the same
>>> timestamp has surely the same content.
>> There's this option that saves a resource but only if the bytes are
>> different from the on-disk bytes.
>> /**
>> * A save option that can be used only with {@link #save(Map)}
>> * to specify that the resource is to be saved only if the new contents
>> * are different from actual contents;
>> * this compares the bytes in the backing store against the new
>> bytes that would be saved.
>> * The value on this option can be either <code>null</code>,
>> * {@link #OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER},
>> * or {@link #OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER}.
>> * @since 2.3
>> */ String OPTION_SAVE_ONLY_IF_CHANGED = "SAVE_ONLY_IF_CHANGED";
> Thanks, this saving option is better to me.
>>>
>>> The problem is that I cannot assume the saving so the changes can be
>>> only "in the memory". In this case I could use listeners to track
>>> the modifications but it can also be happened that the in-memory
>>> resource is removed (e.g. by closing the editor) and there will be
>>> an other in-memory resource instantiated for the given URI where the
>>> changes will happen, so my listener will no longer listen.
>> There could be an arbitrary number of such in-memory copies; one per
>> resource set...
> Yes, but I only have to deal with the resourceSet that is created for
> myURI.
>>> But second time I ask for a resource with the URI I will get the
>>> modified one without no notification from my listener.
>> In any particular resource set you'll either get a new demand loaded
>> one of the one that's been there for a while...
> The provider ensures that for myUri there can be only one in-memory
> resourceSet and I have to deal with only the myUri's resource from it.
>>>
>>>
>>> Of course a brute force solution could be to save the content of the
>>> resource when my method is called at first time and then compares it
>>> whit actual resource what I see at second time call. But I can’t
>>> afford it because of it’s high cost.
>> All in all, I don't really quite understand the context of your
>> question...
> I’ve thought it would be better to hide the concrete context, but
> maybe it could help to demonstrate the problem:
>
> I Would like to make a workspace scoped refactoring for my EMF models
> (i.e. renaming an element will not update only the references in the
> same resourceSet, but the references of other ones involved.) For
> example let's "a.xml" has references to "b.xml".
>
> ResourceSet rs1 = MyResourceSetProvider.getResourceSet("a.xml");
> ResourceSet rs2 = MyResourceSetProvider.getResourceSet("b.xml");
>
> If I rename something in b.xml working with "rs2", the refactoring
> will get "rs1" for a.xml and update the needed references.
>
> The problem is with the undo. When the undo of renaming is executed I
> have to check whether the actual state of the resources of a.xml and
> b.xml were modified from the time of renaming or not. Calling the undo
> for a modified resource could cause erroneous behavior. In normal case
> this kind of checking is not needed because the consistency of the
> model is guaranteed by the command stack (an undo of a command can
> only be visible if the state of the model is the same as after the
> execution of the command). But as there is more than one resourceSet
> is involved, the undo of the refactoring can be visible (so can
> invoked) even if some of the involved resources have already been
> modified (unless if I could spot these situations somehow and the
> difficulty of this spotting, is my problem :).
>
> I hope it makes clearer the problem!
>>>
>>> Note: I’m using Transactional Editing Domain.
>>>
>>>
>>> Thanks for any advice!


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Tracking the modification of a resource given by it’s URI [message #427100 is a reply to message #427089] Mon, 02 February 2009 08:36 Go to previous message
Juergen Aschenbrenner is currently offline Juergen AschenbrennerFriend
Messages: 25
Registered: July 2009
Junior Member
Propably I could not grasp the whole picure, but shouldn't You consider
to make the EditingDomain and thereby the ResourceSet a Singleton.

You might want to have a look at the
TransactionalEditingDomain.Registry.INSTANCE

/Jürgen

Zoltan Balogh schrieb:
> Ed,
>
> comments below.
>
> Ed Merks wrote:
>> Zoltan,
>>
>> Comments below.
>>
>> Zoltan Balogh wrote:
>>> Hi Group,
>>>
>>> I have an interesting problem and I need your advice!
>>>
>>> I have my method which has to be called twice for a given resource by
>>> giving the URI of it. The first time I get the resource using the URI
>>> and make some modifications.
>> So you have a resource set and call getResource(uri, true) and then
>> make changes to the resource.getContents() or some object below it...
> We have a mechanism to get a resourceSet for a given URI (let it be
> "myUri").
>
> ResourceSet myResourceSet = MyResourceSetProvider.getResourceSet(myUri);
> Resource myResource = myResourceSet.getResource(myUri, true);
> // make chages to the myResource.getContents() or some object below it;
>>> The second time (it can be so much later) I have to be sure that the
>>> resource I’m getting this time is not different from the first one
>>> and according to this I will do something or not.
>> Is it the same resource set? You can use setTrackingModification
>> maybe...
> Second time I also get the resorceSet with the same URI.
> ResourceSet myResourceSet2= MyResourceSetProvider.getResourceSet(myUri);
>
> But unfortunately it's not guaranteed that it is the same resourceSet.
> For example if there is no in-memory resourceSet for myUri, there will
> be a new one created.
>>>
>>> It can be easy if I could assume that the resource is saved and
>>> persisted when I get it the second time, because in this case I can
>>> use the timeStamp to decide.
>> Of course it's even possible for another application to change the
>> underlying resource in the file system...
>>> Note that a mistake is allowed in one way, therefore I can tell that
>>> a resource was modified even if it’s not but not vice-versa. E.g.
>>> using the timeStamp it can happens that resource contains the same
>>> information with a bigger timestamp but a resource with the same
>>> timestamp has surely the same content.
>> There's this option that saves a resource but only if the bytes are
>> different from the on-disk bytes.
>> /**
>> * A save option that can be used only with {@link #save(Map)}
>> * to specify that the resource is to be saved only if the new contents
>> * are different from actual contents;
>> * this compares the bytes in the backing store against the new bytes
>> that would be saved.
>> * The value on this option can be either <code>null</code>,
>> * {@link #OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER},
>> * or {@link #OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER}.
>> * @since 2.3
>> */ String OPTION_SAVE_ONLY_IF_CHANGED = "SAVE_ONLY_IF_CHANGED";
> Thanks, this saving option is better to me.
>>>
>>> The problem is that I cannot assume the saving so the changes can be
>>> only "in the memory". In this case I could use listeners to track the
>>> modifications but it can also be happened that the in-memory
>>> resource is removed (e.g. by closing the editor) and there will be an
>>> other in-memory resource instantiated for the given URI where the
>>> changes will happen, so my listener will no longer listen.
>> There could be an arbitrary number of such in-memory copies; one per
>> resource set...
> Yes, but I only have to deal with the resourceSet that is created for
> myURI.
>>> But second time I ask for a resource with the URI I will get the
>>> modified one without no notification from my listener.
>> In any particular resource set you'll either get a new demand loaded
>> one of the one that's been there for a while...
> The provider ensures that for myUri there can be only one in-memory
> resourceSet and I have to deal with only the myUri's resource from it.
>>>
>>>
>>> Of course a brute force solution could be to save the content of the
>>> resource when my method is called at first time and then compares it
>>> whit actual resource what I see at second time call. But I can’t
>>> afford it because of it’s high cost.
>> All in all, I don't really quite understand the context of your
>> question...
> I’ve thought it would be better to hide the concrete context, but maybe
> it could help to demonstrate the problem:
>
> I Would like to make a workspace scoped refactoring for my EMF models
> (i.e. renaming an element will not update only the references in the
> same resourceSet, but the references of other ones involved.) For
> example let's "a.xml" has references to "b.xml".
>
> ResourceSet rs1 = MyResourceSetProvider.getResourceSet("a.xml");
> ResourceSet rs2 = MyResourceSetProvider.getResourceSet("b.xml");
>
> If I rename something in b.xml working with "rs2", the refactoring will
> get "rs1" for a.xml and update the needed references.
>
> The problem is with the undo. When the undo of renaming is executed I
> have to check whether the actual state of the resources of a.xml and
> b.xml were modified from the time of renaming or not. Calling the undo
> for a modified resource could cause erroneous behavior. In normal case
> this kind of checking is not needed because the consistency of the model
> is guaranteed by the command stack (an undo of a command can only be
> visible if the state of the model is the same as after the execution of
> the command). But as there is more than one resourceSet is involved, the
> undo of the refactoring can be visible (so can invoked) even if some of
> the involved resources have already been modified (unless if I could
> spot these situations somehow and the difficulty of this spotting, is my
> problem :).
>
> I hope it makes clearer the problem!
>>>
>>> Note: I’m using Transactional Editing Domain.
>>>
>>>
>>> Thanks for any advice!
Previous Topic:how to model an iterator?
Next Topic:Eannotation at the package level
Goto Forum:
  


Current Time: Thu Apr 25 23:45:46 GMT 2024

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

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

Back to the top