[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.technology.emft] Re: [EMF Compare] MergeService doesn't copy a child non-containment reference

Bryan,

I believe this is indeed the right approach ... and that would mean there is a case I haven't thought of, and that I didn't encouter in my tests. Could you raise a bug with your stack trace and the models you've used to produce this error?

Laurent Goubet
Obeo

Bryan Hunt a écrit :
Hi Laurent,

We are just now getting back to working on our merge problem. We are now getting a ClassCastException when we try to do the merge. Here is how are are setting up the merge:

Model model = library.getModel(false);

MatchResourceSet match = MatchService.doResourceSetMatch(root.eResource().getResourceSet(), model.eResource().getResourceSet(), Collections.<String, Object> emptyMap());

DiffResourceSet diff = DiffService.doDiff(match, false);

for (DiffModel resourceDiff : diff.getDiffModels())
{
List<DiffElement> differences = new ArrayList<DiffElement>(resourceDiff.getOwnedElements());
MergeService.merge(differences, false);
}


When the merger gets to handleMutuallyDerrivedReferences() the switch statement takes the case EcorePackage.ECLASS__ESUPER_TYPES and fails when it tries to cast diff to a ReferenceChangeRightTarget. diff is of the type UpdateReferenceImpl. Here is the section of code in question:

private void handleMutuallyDerivedReferences() {
DiffElement toRemove = null;
if (diff instanceof ReferenceChange) {
final EReference reference = ((ReferenceChange)diff).getReference();
switch (reference.getFeatureID()) {
case EcorePackage.ECLASS__ESUPER_TYPES:
final EObject referenceType;
if (diff instanceof ReferenceChangeLeftTarget) {
referenceType = ((ReferenceChangeLeftTarget)diff).getRightTarget();
} else {
referenceType = ((ReferenceChangeRightTarget)diff).getLeftTarget(); <<---- exception here
}



Are we taking the right approach with our code? Any ideas on how to fix this?


Bryan

On 2009-08-20 02:47:21 -0500, laurent Goubet <laurent.goubet@xxxxxxx> said:


Hi Stephen,

MatchService.doResourcesetMatch should indeed be the way to go in your
case. Whether you merge the differences or not, using anything else to
match resources containing links to other resources would give erroneous
results.

Other than that ... DiffResourceSet.getSubDiffElements() doesn't exist.
DiffResourceSet.getDiffModels() will return a DiffModel for each
resources pair (Resource A from ResourceSet RS1 matched with Resource A'
from ResourceSet RS2 will yield on DiffModel, Resource B from RS1 and
Resource B' from RS2 ....).

DiffModel.getOwnedElements() will return a "root" DiffElement
corresponding to every root of the compared resources, and
DiffElement.getSubDiffElements() on these roots will give you the actual
changes detected, which you can then merge through the MergeService.

DiffResourceSet.getResourceDiffs() will contain DiffElements if there
are more resources in one ResourceSet than there are in the other
(namely, a resource now links to a new "other" resource).

Laurent Goubet
Obeo

P.S : just realized the copier we use to merge differences is contextual
to a DiffModel, not to the DiffResourceSet ... I don't know if we'll
properly restore dangling inter-model links because of that. I'll take a
look when I come back to EMF Compare.

Stephen McCants a écrit :
Anyone have any ideas?  We are still stuck.
Thanks!

--Stephen

Stephen McCants wrote:
Hello Laurent,
Thanks for your reply.  I just got back from vacation today, so I
just looked at your emails today.

With two differences as you've described, EMF Compare will indeed need two steps for this child reference to be copied : you have an added element A with a reference towards the child C of another added element B. Merging only A will not copy C since B hasn't been copied yet, but merging B subsequently will copy C _and_ restore the link from A to C.

That makes sense, but I think where I may be running into problems is that A and B are in different resources, but the same resource set. We are trying a MatchService.doMatch(A1, A2), so that will only see the changes to A and not to B?

We tried switching to a doResourceSetMatch(...), but that ran into
some problems. We got a DiffResourceSet back, but
DiffResourceSet.getSubDiffElements() returns an empty array so we have
nothing to merge with. Looking into the DiffResourceSet I can see it
has a "root" object that is contained by a DifferenceImpl (of some type).


Is there an example of how to merge differences between resource sets?

Thanks for your help!

--Stephen



This message has one or more attachments. Select "Save Attachments" from the File menu to save.
begin:vcard
fn:Laurent Goubet



begin:vcard
fn:Laurent Goubet
n:Goubet;Laurent
org:<a href="http://www.obeo.fr/";>Obeo</a>
email;internet:laurent.goubet@xxxxxxx
url:http://www.obeo.fr
version:2.1
end:vcard