Home » Modeling » EMF » Why does ChangeRecorder record backwards?
Why does ChangeRecorder record backwards? [message #419616] |
Thu, 29 May 2008 05:15 |
Al B Messages: 130 Registered: July 2009 |
Senior Member |
|
|
Hi,
We have run some tests to look at the implications of using the EMF
ChangeRecorder to monitor model edits.
However, one odd thing is that the recorder records the model changes and
stores them backwards. So, for instance, if we add an activity group, and
serialize the record of that transaction, we get the following:
<?xml version="1.0" encoding="ASCII"?>
<change:ChangeDescription xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI"
xmlns:change="http://www.eclipse.org/emf/2003/Change">
<objectChanges>
<key href="plan.xmi#///@activityGroups.0"/>
<value featureName="plan" set="false"/>
<value featureName="dynamic.FixedInParent" set="false"/>
</objectChanges>
<objectChanges>
<key href="plan.xmi#//"/>
<value featureName="activityGroups" set="false"/>
</objectChanges>
</change:ChangeDescription>
The first "objectChanges" element shows that the the 'plan' feature
(get/setPlan) of the activity group is 'unset.' Similarly, the
'activityGroups' feature (get/setActivityGroups) is also 'unset'.
Also, when we read the description back in, we get <key
href="plan.xmi#///@activityGroups.0"/>; which refers to the activity group
at index 0 of the plan. However, the ResourceSet cannot resolve it. So, we
have to create this total hack to make it work:
if (uriString.startsWith("plan.xmi#///@activityGroups.")) {
int i = uriString.lastIndexOf('.');
int index = Integer.parseInt(uriString.substring(i+1));
return CommonUtils.getAdapter(plan.getActivityGroups().get(index),
EObject.class);
} else if (uriString.equals("plan.xmi#//")) {
return CommonUtils.getAdapter(plan, EObject.class);
}
By works, I mean, we can record a change, serialize it, de-serialize it,
apply (undo) the change.
So, any guidance in this will be greatly appreciated!
|
|
|
Re: Why does ChangeRecorder record backwards? [message #419621 is a reply to message #419616] |
Thu, 29 May 2008 11:13 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
AJ,
The change recorder describes the changes relative to the current state
of the model instance. That's very important from a serialization point
of view since it needs to reference the changed objects and those
objects are in the final state. So objects that are removed from the
original instance are dangling references and if they are to be
serialized, they need to be contained by a resource. Hence they are
modified to be contained by the ChangeDescription itself. Also objects
might be contained by a different parent or might be in a different
position in the list. All these things affect the serialization. It
would be extremely difficult to try to serialize it as if the instance
where in the original state.
Of course you can call applyAndReverse to restore the instance to the
original state and to transform the change description into a
description of how to get back to the final state. If you serialize
that, you'll be able to deserialize it relative to another copy of the
original instances and apply it to make that copy move to the same final
state. And of course you can call applyAndReverse as many times as you
like to toggle between the two states (which is what makes it so useful
for implementing undo and redo).
So while it seems surprising and perhaps even unintuitive for it to work
this way, it's the only way we could devise that something that
serializes...
AJ wrote:
> Hi,
>
> We have run some tests to look at the implications of using the EMF
> ChangeRecorder to monitor model edits.
>
> However, one odd thing is that the recorder records the model changes
> and stores them backwards. So, for instance, if we add an activity
> group, and serialize the record of that transaction, we get the
> following:
>
> <?xml version="1.0" encoding="ASCII"?>
> <change:ChangeDescription xmi:version="2.0"
> xmlns:xmi="http://www.omg.org/XMI"
> xmlns:change="http://www.eclipse.org/emf/2003/Change">
> <objectChanges>
> <key href="plan.xmi#///@activityGroups.0"/>
> <value featureName="plan" set="false"/>
> <value featureName="dynamic.FixedInParent" set="false"/>
> </objectChanges>
> <objectChanges>
> <key href="plan.xmi#//"/>
> <value featureName="activityGroups" set="false"/>
> </objectChanges>
> </change:ChangeDescription>
>
> The first "objectChanges" element shows that the the 'plan' feature
> (get/setPlan) of the activity group is 'unset.' Similarly, the
> 'activityGroups' feature (get/setActivityGroups) is also 'unset'.
>
> Also, when we read the description back in, we get <key
> href="plan.xmi#///@activityGroups.0"/>; which refers to the activity
> group at index 0 of the plan. However, the ResourceSet cannot resolve
> it. So, we have to create this total hack to make it work:
>
> if (uriString.startsWith("plan.xmi#///@activityGroups.")) {
> int i = uriString.lastIndexOf('.');
> int index = Integer.parseInt(uriString.substring(i+1));
> return CommonUtils.getAdapter(plan.getActivityGroups().get(index),
> EObject.class);
> } else if (uriString.equals("plan.xmi#//")) {
> return CommonUtils.getAdapter(plan, EObject.class);
> }
>
> By works, I mean, we can record a change, serialize it, de-serialize
> it, apply (undo) the change.
>
> So, any guidance in this will be greatly appreciated!
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| |
Re: Why does ChangeRecorder record backwards? [message #419633 is a reply to message #419632] |
Thu, 29 May 2008 18:18 |
Ed Merks Messages: 33140 Registered: July 2009 |
Senior Member |
|
|
AJ,
Whenever people ask me questions about URIs in their serialized
resources I always ask the same questions. What was the URI of the
resource containing the reference to the object and what was the URI of
the resource contained the referenced object? They generally should
both be absolute and then the reference will be serialized as a relative
reference when that's possible for the two absolute URIs. On the other
end, the reference will be made absolute again based on resolving it
against the URI of the resource that contains the reference to the
object. URI.resolve/deresolve does that work. So pay very close
attention to your URIs. Try to ensure they are always absolute. Look
closely at all the resources in your resource set to see if maybe you
have two different plan.xmi resources...
AJ wrote:
> Ed,
>
> Thanks for the reply. One more question. Why does the ResourceSet
> cannot resolve the <key href="plan.xmi#///@activityGroups.0"/> when we
> read the description back in?
> We created a hack to make it work (see below), but I wonder if you
> have any other suggestion(s).
>
> if (uriString.startsWith("plan.xmi#///@activityGroups.")) {
> int i = uriString.lastIndexOf('.');
> int index = Integer.parseInt(uriString.substring(i+1));
> return CommonUtils.getAdapter(plan.getActivityGroups().get(index),
> EObject.class);
> } else if (uriString.equals("plan.xmi#//")) {
> return CommonUtils.getAdapter(plan, EObject.class);
> }
>
>
> Thanks again!
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Goto Forum:
Current Time: Tue Apr 23 17:49:54 GMT 2024
Powered by FUDForum. Page generated in 0.03138 seconds
|