Remy,
Comments below.
Remy Suen wrote:
Hi everyone,
EMF youngling here. I would like to humbly request assistance and input
from the EMF Jedi Masters that are in the audience.
I've been tasked to try to solve a 3.x workbench (perspective)
persistence problem that has likely plagued anyone that has ever tried
to add something to a perspective (bug 48060 would be one such
example).[1]
The basic gist of the problem here is that the perspective is only ever
loaded once on 3.x and once the user changes something, that
perspective is saved and persisted when the workbench shuts down. Now,
say JDT adds some new view and places it in the default perspective
layout in 3.6 and I upgrade from 3.5 to 3.6, that new view will _not_
show up when I restart. This method of preserving workbench
state/layout makes the discovery of new features very difficult for the
user.
We would like to be able to solve this problem for e4 by merging user
changes into the underlying model.
At the moment, I am implementing this by using ChangeRecorder from the
org.eclipse.emf.ecore.change bundle. I start monitoring the workbench
model once it's been constructed and serialize the deltas when the
workbench shuts down. The next time the workbench starts up, I load the
model (this may be the original or a completely new one as described in
the example above) and then deserialize the deltas and (try to) apply
the deltas to the model.
That's an interesting approach.
Let's say a stack has parts A, B, and C in it.
The user closes C.
In v2, the stack now has parts A, B, C, and a new part D in it.
The merged result should be A, B, and D.
The above example isn't rocket science but it becomes more interesting
once the user starts creating new model objects as a result of
customizing the layout of parts.
Consider a stack that has two parts, A and B, with a generated id of
partContainer.0.
Are you talking about URI fragments here? E.g., //@partContainer.0
Now you drag part A to the left side of the stack until you get
that rectangular outline indicator for creating a new stack and you
release the mouse.
Now you have two parts, A and B, each in their own stack. However, the
id of partContainer.0 is now void because it's pointing at the
container the user created instead of the original which is now
identified as partContainer.1, as calculated via index positions.
Index-based references are fragile in this way, but that's an issue
primarily when the references are cross resource and the referenced
resource can change on its own. I wonder if in your scenario something
as simple as calling EcoreUtil.resolveAll would force all proxies to
resolve before you start applying changes would avoid the problem....
It's not clear to me how we can solve this problem at the moment. One
could imagine assigning custom UUIDs to every single model object. That
seems to tie with bug 161599[2] in a way but I'm not really positive
here since I'm not sure if that would tie in with the EMF editor such
that every created object would automatically be assigned a UUID. If
it's only generated during serialization/deserialization then it sounds
like they would change over time which is definitely not what we want.
I suppose a new attribute could always be added to the model and then
the object construction code could be customized to have a UUID set to
a field.
Specializing XMIResourceImpl to override useUUIDs to return true will
ensure that a UUID is associated with the object as soon as it's
attached to that resource; these UUIDs are preserved if you move the
object from one resource to another UUID-enabled resource. They won't
change over time, but take a lot of space to maintain...
Is using ChangeRecorder the way to go about trying to solve this
problem?
It seems like a cool way.
I looked at EMF Compare briefly but there are some reservations
since that would require the serialization of the entire (user) model
unlike the ChangeRecorder where we would only save the deltas. Rolling
our own custom merging strategy naturally gives the developer a lot of
control over the resultant model. On the other hand, I realize that the
SDK, and other Eclipse.org projects, are often criticized for suffering
from the NIH syndrome so I want to make sure that this is the right
path to take before I start diving deeper into this problem as I
believe you can customize EMF Compare via its interfaces (such as
IDiffEngine and IMerger).
Yes I imagine a completely generic solution should be possible.
Of course, I am also welcome to other suggestions that don't
involve ChangeRecorder and EMF Compare.
It sounds like the only problem you're having is with references. It
might be as simple as resolving all references early. Otherwise, you
might also consider changes to the model. Is there any existing
attribute on a partContainer that might act as a key (unique within
that one reference) or as an ID (unique within the whole resource)?
For example, the EPackage.eClassifiers must have unique names, so
ENamedElement.name could be added to the EReference.eKeys for th
EPackage.eClassifiers EReference (for the meta pain this causes) and in
that case, the serialization would look like
@eClassifiers[name='value'] rather than @eClassifiers.<index>.
Is there any such information on these references that would serve this
type of purpose?
Please provide your thoughts on this topic in bug 295524, thank you.[3]
Oops, I did all the commenting in line like it was a newsgroup
question. Sorry.
[1] - https://bugs.eclipse.org/bugs/show_bug.cgi?id=48060
[2] - https://bugs.eclipse.org/bugs/show_bug.cgi?id=161599
[3] - https://bugs.eclipse.org/bugs/show_bug.cgi?id=295524
Regards,
Remy
----------
Remy Suen
Eclipse Platform/UI Committer
IBM Ottawa
613-356-5162
_______________________________________________
e4-dev mailing list
e4-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/e4-dev
|