Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Compare » Problem with merge: duplicate objects are created
Problem with merge: duplicate objects are created [message #1695969] Wed, 20 May 2015 16:17 Go to next message
Erwan Bousse is currently offline Erwan BousseFriend
Messages: 7
Registered: May 2015
Junior Member
Hi!

I am trying to use EMFCompare programmatically to find the differences between two models A and B, and to resolve all the differences so that in the end A is exactly the same as B.

However I have the following issue : in some situations, objects in B that are copied in A are copied twice. This seems to happen when an object is referenced twice, therefore when the two diffs are taken into account, the object is copied twice.

I have written this custom merger :

class Merger extends AbstractMerger {

	public Merger() {
		setRegistry(EMFCompareRCPPlugin.getDefault().getMergerRegistry());
	}

	@Override
	public boolean isMergerFor(Diff target) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void copyRightToLeft(Diff target, Monitor monitor) {
		this.mergeDiff(target, true, monitor);
	}

	@Override
	public void copyLeftToRight(Diff target, Monitor monitor) {
		this.mergeDiff(target, false, monitor);
	}
}


And the following code to resolve the differences :

EObject left = ....;
EObject right = ....;

IComparisonScope scope = new DefaultComparisonScope(left, right, null);
EMFCompare build = EMFCompare.builder().build();
Comparison comparison = build.compare(scope);
List<Diff> differences = comparison.getDifferences();

Merger merger = new Merger();
BasicMonitor monitor = new BasicMonitor();
for (Diff diff : differences)
{
		// if reference, use the merger.
		merger.copyLeftToRight(diff, monitor);
		diff.setState(DifferenceState.UNRESOLVED);
	}
}


Maybe I am doing the whole thing wrong?

Thanks in advance,
Re: Problem with merge: duplicate objects are created [message #1696167 is a reply to message #1695969] Fri, 22 May 2015 13:51 Go to previous messageGo to next message
Erwan Bousse is currently offline Erwan BousseFriend
Messages: 7
Registered: May 2015
Junior Member
So I finally solved my problem by writing this very ugly merger :

class Merger extends AbstractMerger {

	/**
	 * We want to bypass the reference merger that is eventually called by the 
	 * abstract merger, so we create this merger with a very high ranking.
	 * 
	 * The goal of the bypass is th replace the operation createCopy, so that
	 * objects are not created multiple times.
	 *
	 */
	public static class CustomReferenceMerger extends ReferenceChangeMerger {

		final EcoreUtil.Copier copier = new EMFCompareCopier();

		protected EObject createCopy(EObject referenceObject) {

			if (copier.containsKey(referenceObject))
				return copier.get(referenceObject);
			return copier.copy(referenceObject);
		}

		@Override
		public int getRanking() {
			return Integer.MAX_VALUE;
		}

	}

	public Merger() {
		setRegistry(EMFCompareRCPPlugin.getDefault().getMergerRegistry());
		getRegistry().add(new CustomReferenceMerger());
	}

	@Override
	public boolean isMergerFor(Diff target) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void copyRightToLeft(Diff target, Monitor monitor) {
		this.mergeDiff(target, true, monitor);
	}

	@Override
	public void copyLeftToRight(Diff target, Monitor monitor) {
		this.mergeDiff(target, false, monitor);
	}

}


This workaround aims at bypassing the "createCopy" operation that is used by a merger to create new objects. The original version creates a copier, makes a copy, then throw the copier away, hence making it impossible to avoid duplicating objects by checking if the copy hadn't already been done.

However, the "mergeDiff" operation uses a registry to find the correct merger for references, which means that our Merger is not used for "createCopy". Hence this "CustomReferenceMerger" with the highest ranking in the registry, with a new working createCopy operation.

With this hack, I can now transform successfully a model A into a model B by merging the found differences into A. But I guess that there is a better way to do so Smile.
Re: Problem with merge: duplicate objects are created [message #1696369 is a reply to message #1696167] Tue, 26 May 2015 07:14 Go to previous message
Laurent Goubet is currently offline Laurent GoubetFriend
Messages: 1858
Registered: July 2009
Senior Member
Erwan,

There are differences for every single diff in the model, including equivalent differences (for example differences on the two ends of an eOpposite relationship). Therefore, merging "all" diferences in the Comparison model from one side to the other without regards for the requirements, implcations, equivalences and conflicts will most likely corrupt the target model (for example, by creating multiple copies of the same object).

Please look at the entry in the FAQ on how to use EMF Compare programmatically, especially on the last lines using the BatchMerger.

Laurent Goubet
Obeo
Previous Topic:NLP on comparing two xml files
Next Topic:Compare nodes with different parent hierarchy
Goto Forum:
  


Current Time: Sat Sep 22 14:40:26 GMT 2018

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

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

Back to the top