Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Fleck2017-03-13 05:06:12 -0400
committerLaurent Goubet2017-06-27 10:18:45 -0400
commit8bc41b3003625c3b09dc171f0ab383929ce04d72 (patch)
tree4fe58bc48767362359604e2540f4228d75cece72
parent674d7eb2c3ffae6c0d3328569d43445c95b68535 (diff)
downloadorg.eclipse.emf.compare-8bc41b3003625c3b09dc171f0ab383929ce04d72.tar.gz
org.eclipse.emf.compare-8bc41b3003625c3b09dc171f0ab383929ce04d72.tar.xz
org.eclipse.emf.compare-8bc41b3003625c3b09dc171f0ab383929ce04d72.zip
[514415] Relationships between diffs should be cached
Add an interface for diff relationship computers that are able to calculate diff relationships and provide two implementations: - Standard implementation replacing MergeDependenciesUtil methods. - Caching implementation keeping the results until invalidated. The computers are usable whenever diff relationships are calculated. Either an explicit instance is provided or the standard implementation is used as fallback: - ComputeDiffsToMerge calculates the order in which diffs are merged. - BatchMerger propagates to ComputeDiffsToMerge. - DependencyData finds required/rejected diffs for selected diffs. The instances are created in two scenarios: - The resource mapping mergers create their own caching instance and invalidate the cache after performing their operation. - The EMF SMV creates its own caching instance for the UI, stored in the EMFCompareConfiguration and invalidates the cache when another comparison is used. Includes tests. Bug: 514415 Change-Id: Id2a56db00b6ca80db2602b3f207377e72a9d80b8 Signed-off-by: Martin Fleck <mfleck@eclipsesource.com>
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/command/MergeAllCommandTests.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/CascadingFilterRefinementTest.java9
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableRefinementTest.java3
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableTest.java6
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434822.java16
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434827.java7
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828.java4
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828_2.java4
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/configuration/EMFCompareConfiguration.java26
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/AdditiveResourceMappingMerger.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java13
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DependencyData.java29
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java15
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractMergeRunnable.java45
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java19
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAllNonConflictingAction.java8
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeContainedNonConflictingAction.java8
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeNonConflictingRunnable.java18
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeRunnableImpl.java11
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java36
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java5
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java26
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/checkers/MergeDependenciesChecker.java11
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java420
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java4
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java205
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java54
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/CachingDiffRelationshipComputer.java524
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ComputeDiffsToMerge.java45
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/DiffRelationshipComputer.java233
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IDiffRelationshipComputer.java152
31 files changed, 1677 insertions, 301 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/command/MergeAllCommandTests.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/command/MergeAllCommandTests.java
index 21e3d10ac..c47d2183b 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/command/MergeAllCommandTests.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/command/MergeAllCommandTests.java
@@ -39,6 +39,7 @@ import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.MergeNonConflictingRunnable;
import org.eclipse.emf.compare.ide.ui.tests.command.data.MergeAllCommandInputData;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.DefaultComparisonScope;
import org.eclipse.emf.compare.scope.IComparisonScope;
@@ -86,7 +87,7 @@ public class MergeAllCommandTests {
.addAll(ImmutableList.of(leftResource, rightResource, originResource)).build();
MergeNonConflictingRunnable runnable = new MergeNonConflictingRunnable(isLeftEditable,
- isRightEditable, mergeMode);
+ isRightEditable, mergeMode, new DiffRelationshipComputer(mergerRegistry));
MergeAllNonConflictingCommand command = new MergeAllNonConflictingCommand(changeRecorder, notifiers,
comparison, leftToRight, mergerRegistry, runnable);
@@ -155,7 +156,7 @@ public class MergeAllCommandTests {
.addAll(ImmutableList.of(leftResource, rightResource, originResource)).build();
MergeNonConflictingRunnable runnable = new MergeNonConflictingRunnable(isLeftEditable,
- isRightEditable, mergeMode);
+ isRightEditable, mergeMode, new DiffRelationshipComputer(mergerRegistry));
MergeAllNonConflictingCommand command = new MergeAllNonConflictingCommand(changeRecorder, notifiers,
comparison, leftToRight, mergerRegistry, runnable);
@@ -224,7 +225,7 @@ public class MergeAllCommandTests {
.addAll(ImmutableList.of(leftResource, rightResource, originResource)).build();
MergeNonConflictingRunnable runnable = new MergeNonConflictingRunnable(isLeftEditable,
- isRightEditable, mergeMode);
+ isRightEditable, mergeMode, new DiffRelationshipComputer(mergerRegistry));
MergeAllNonConflictingCommand command = new MergeAllNonConflictingCommand(changeRecorder, notifiers,
comparison, leftToRight, mergerRegistry, runnable);
@@ -293,7 +294,7 @@ public class MergeAllCommandTests {
.addAll(ImmutableList.of(leftResource, rightResource, originResource)).build();
MergeNonConflictingRunnable runnable = new MergeNonConflictingRunnable(isLeftEditable,
- isRightEditable, mergeMode);
+ isRightEditable, mergeMode, new DiffRelationshipComputer(mergerRegistry));
MergeAllNonConflictingCommand command = new MergeAllNonConflictingCommand(changeRecorder, notifiers,
comparison, leftToRight, mergerRegistry, runnable);
@@ -369,7 +370,7 @@ public class MergeAllCommandTests {
.addAll(ImmutableList.of(leftResource, originResource)).build();
MergeNonConflictingRunnable runnable = new MergeNonConflictingRunnable(isLeftEditable,
- isRightEditable, mergeMode);
+ isRightEditable, mergeMode, new DiffRelationshipComputer(mergerRegistry));
MergeAllNonConflictingCommand command = new MergeAllNonConflictingCommand(changeRecorder, notifiers,
comparison, mergeMode.isLeftToRight(isLeftEditable, isRightEditable), mergerRegistry,
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/CascadingFilterRefinementTest.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/CascadingFilterRefinementTest.java
index a52055198..61f72fe82 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/CascadingFilterRefinementTest.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/CascadingFilterRefinementTest.java
@@ -33,7 +33,8 @@ import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.ide.ui.tests.framework.RuntimeTestRunner;
import org.eclipse.emf.compare.ide.ui.tests.framework.annotations.Compare;
import org.eclipse.emf.compare.ide.ui.tests.framework.internal.CompareTestSupport;
-import org.eclipse.emf.compare.internal.merge.MergeDependenciesUtil;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMergeOptionAware;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
@@ -46,7 +47,7 @@ import org.junit.runner.RunWith;
*
* @author Martin Fleck <mfleck@eclipsesource.com>
*/
-@SuppressWarnings({"restriction", "nls" })
+@SuppressWarnings({"nls" })
@RunWith(RuntimeTestRunner.class)
public class CascadingFilterRefinementTest {
@@ -172,8 +173,8 @@ public class CascadingFilterRefinementTest {
*/
public void verifyRefinement(List<Diff> differences, boolean mergeRightToLeft) {
for (Diff diff : differences) {
- Set<Diff> resultingMerges = MergeDependenciesUtil.getAllResultingMerges(diff, MERGER_REGISTRY,
- mergeRightToLeft);
+ IDiffRelationshipComputer computer = new DiffRelationshipComputer(MERGER_REGISTRY);
+ Set<Diff> resultingMerges = computer.getAllResultingMerges(diff, mergeRightToLeft);
assertTrue("Not all refined diffs are in resulting merges.",
resultingMerges.containsAll(diff.getRefines()));
assertTrue("Not all refining diffs are in resulting merges.",
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableRefinementTest.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableRefinementTest.java
index e1877bcad..e0e07ecf6 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableRefinementTest.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableRefinementTest.java
@@ -32,6 +32,7 @@ import org.eclipse.emf.compare.internal.spec.ConflictSpec;
import org.eclipse.emf.compare.internal.spec.DiffSpec;
import org.eclipse.emf.compare.internal.spec.MatchSpec;
import org.eclipse.emf.compare.merge.AbstractMerger;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.junit.Assert;
import org.junit.Test;
@@ -570,7 +571,7 @@ public class MergeNonConflictingRunnableRefinementTest {
throw new IllegalArgumentException();
}
MergeNonConflictingRunnable mergeNonConflicting = new MergeNonConflictingRunnable(isLeftEditable,
- isRightEditable, mergeMode);
+ isRightEditable, mergeMode, new DiffRelationshipComputer(MERGER_REGISTRY));
mergeNonConflicting.merge(comparison, leftToRight, MERGER_REGISTRY);
}
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableTest.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableTest.java
index b1d5ad030..c460c197d 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableTest.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/MergeNonConflictingRunnableTest.java
@@ -30,6 +30,7 @@ import com.google.common.collect.Iterators;
import java.util.Iterator;
+import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Monitor;
@@ -44,6 +45,7 @@ import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ReferenceChange;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.MergeNonConflictingRunnable;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMergeCriterion;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.merge.IMerger.Registry;
@@ -502,6 +504,7 @@ public class MergeNonConflictingRunnableTest {
when(diff.getRefinedBy()).thenReturn(new BasicEList<Diff>());
when(diff.getRefines()).thenReturn(new BasicEList<Diff>());
when(diff.getState()).thenReturn(UNRESOLVED);
+ when(diff.eAdapters()).thenReturn(new BasicEList<Adapter>());
return diff;
}
@@ -634,7 +637,8 @@ public class MergeNonConflictingRunnableTest {
default:
throw new IllegalArgumentException();
}
- return new MergeNonConflictingRunnable(isLeftEditable, isRightEditable, mergeMode) {
+ return new MergeNonConflictingRunnable(isLeftEditable, isRightEditable, mergeMode,
+ new DiffRelationshipComputer(mergerRegistry)) {
@Override
protected void markAsMerged(Diff diff, MergeMode mode, boolean mergeRightToLeft,
Registry registry) {
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434822.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434822.java
index 953cc124f..e881dae12 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434822.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434822.java
@@ -28,6 +28,7 @@ import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.MergeRunnableImpl;
import org.eclipse.emf.compare.internal.merge.MergeDataImpl;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
import org.eclipse.emf.compare.scope.DefaultComparisonScope;
@@ -112,7 +113,8 @@ public class TestBug434822 {
public void testMergeDataAfterAcceptingDeletion() {
ArrayList<Diff> uiDiff = Lists.newArrayList(rightDelete);
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(uiDiff, false, mergerRegistry);
// Assert merge data and diff states
@@ -131,7 +133,8 @@ public class TestBug434822 {
// filter activated).
ArrayList<Diff> uiDiff = Lists.newArrayList(rightDelete, leftMove);
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(uiDiff, false, mergerRegistry);
// Assert merge data and diff states
@@ -152,7 +155,8 @@ public class TestBug434822 {
*/
ArrayList<Diff> uiDiff = Lists.newArrayList(rightDelete);
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, REJECT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, REJECT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(uiDiff, false, mergerRegistry);
// Assert merge data and diff states
@@ -169,7 +173,8 @@ public class TestBug434822 {
// Mocks the UI behavior of UI if the movement diff is selected for merging.
ArrayList<Diff> uiDiff = Lists.newArrayList(leftMove);
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(uiDiff, false, mergerRegistry);
// Assert merge data
@@ -187,7 +192,8 @@ public class TestBug434822 {
// Mocks the UI behavior of UI if the movement diff is selected for merging.
ArrayList<Diff> uiDiff = Lists.newArrayList(leftMove);
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, REJECT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, REJECT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(uiDiff, false, mergerRegistry);
// Assert merge data
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434827.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434827.java
index 9f74b0e4a..1be009ab5 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434827.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434827.java
@@ -32,6 +32,7 @@ import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.Merg
import org.eclipse.emf.compare.internal.merge.IMergeData;
import org.eclipse.emf.compare.internal.merge.MergeDataImpl;
import org.eclipse.emf.compare.internal.spec.ReferenceChangeSpec;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
import org.eclipse.emf.compare.scope.DefaultComparisonScope;
@@ -133,7 +134,8 @@ public class TestBug434827 {
// The subDiff is not added in this list because it is not considered as a cascading diff.
ArrayList<Diff> uiDiff = Lists.newArrayList(deletionDiff);
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(uiDiff, false, mergerRegistry);
Node rootNode = (Node)left.getContents().get(0);
@@ -168,7 +170,8 @@ public class TestBug434827 {
// The subDiff is not added in this list because it is not considered as a cascading diff.
ArrayList<Diff> uiDiff = Lists.newArrayList(deletionDiff);
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, REJECT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, REJECT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(uiDiff, false, mergerRegistry);
Node rootNode = (Node)left.getContents().get(0);
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828.java
index e4af7d616..89bdd0901 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828.java
@@ -30,6 +30,7 @@ import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.MergeRunnableImpl;
import org.eclipse.emf.compare.internal.merge.MergeDataImpl;
import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
import org.eclipse.emf.compare.scope.DefaultComparisonScope;
@@ -126,7 +127,8 @@ public class TestBug434828 {
*/
@Test
public void testAcceptConflictDiffWithConflictingDiffWithRequiredBy() {
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(Collections.singletonList(refChangeDiff), false, mergerRegistry);
assertEquals(MERGED, refChangeDiff.getState());
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828_2.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828_2.java
index 32c4d830c..d92e86846 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828_2.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/structuremergeviewer/actions/TestBug434828_2.java
@@ -30,6 +30,7 @@ import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.MergeRunnableImpl;
import org.eclipse.emf.compare.internal.merge.MergeDataImpl;
import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
import org.eclipse.emf.compare.scope.DefaultComparisonScope;
@@ -127,7 +128,8 @@ public class TestBug434828_2 {
*/
@Test
public void testAcceptConflictDiffWithConflictingDiffWithRequiredBy() {
- MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT);
+ MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, ACCEPT,
+ new DiffRelationshipComputer(mergerRegistry));
mergeRunnable.merge(Collections.singletonList(refChangeDiff), false, mergerRegistry);
assertEquals(MERGED, refChangeDiff.getState());
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/configuration/EMFCompareConfiguration.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/configuration/EMFCompareConfiguration.java
index cefe2265f..38969b3a0 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/configuration/EMFCompareConfiguration.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/configuration/EMFCompareConfiguration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2016 Obeo and others.
+ * Copyright (c) 2013, 2017 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
* Obeo - initial API and implementation
* Conor O'Mahony - bug 507465
* Martin Fleck - bug 483798
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.configuration;
@@ -29,11 +30,15 @@ import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
+import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.impl.AdapterFactoryChange;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.impl.CompareEditingDomainChange;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.impl.ComparisonAndScopeChange;
+import org.eclipse.emf.compare.rcp.ui.internal.configuration.impl.DiffRelationshipComputerChange;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.impl.EMFComparatorChange;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.impl.MergePreviewModeChange;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter;
@@ -61,6 +66,9 @@ public class EMFCompareConfiguration extends ForwardingCompareConfiguration impl
private static final String ADAPTER_FACTORY = EMFCompareIDEUIPlugin.PLUGIN_ID + ".ADAPTER_FACTORY"; //$NON-NLS-1$
+ private static final String DIFF_RELATIONSHIP_COMPUTER = EMFCompareIDEUIPlugin.PLUGIN_ID
+ + ".DIFF_RELATIONSHIP_COMPUTER"; //$NON-NLS-1$
+
private static final String PREVIEW_MERGE_MODE = EMFCompareIDEUIPlugin.PLUGIN_ID + ".PREVIEW_MERGE_MODE"; //$NON-NLS-1$
private static final String COMPARISON_SCOPE = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARISON_SCOPE"; //$NON-NLS-1$ ;
@@ -125,6 +133,11 @@ public class EMFCompareConfiguration extends ForwardingCompareConfiguration impl
if (getProperty(DISPLAY_SAVE_ACTION) == null) {
setProperty(DISPLAY_SAVE_ACTION, Boolean.TRUE);
}
+
+ if (getProperty(DIFF_RELATIONSHIP_COMPUTER) == null) {
+ setProperty(DIFF_RELATIONSHIP_COMPUTER,
+ new DiffRelationshipComputer(EMFCompareRCPPlugin.getDefault().getMergerRegistry()));
+ }
}
/**
@@ -163,6 +176,7 @@ public class EMFCompareConfiguration extends ForwardingCompareConfiguration impl
compareConfiguration.setProperty(SMV_FILTERS, null);
compareConfiguration.setProperty(EDITING_DOMAIN, null);
compareConfiguration.setProperty(ADAPTER_FACTORY, null);
+ compareConfiguration.setProperty(DIFF_RELATIONSHIP_COMPUTER, null);
compareConfiguration.setProperty(SMV_GROUP_PROVIDERS, null);
compareConfiguration.setProperty(PREVIEW_MERGE_MODE, null);
compareConfiguration.setProperty(DISPLAY_GROUP_PROVIDERS, null);
@@ -201,6 +215,10 @@ public class EMFCompareConfiguration extends ForwardingCompareConfiguration impl
return (AdapterFactory)getProperty(ADAPTER_FACTORY);
}
+ public IDiffRelationshipComputer getDiffRelationshipComputer() {
+ return (IDiffRelationshipComputer)getProperty(DIFF_RELATIONSHIP_COMPUTER);
+ }
+
/**
* {@inheritDoc}
*
@@ -293,6 +311,12 @@ public class EMFCompareConfiguration extends ForwardingCompareConfiguration impl
getEventBus().post(new AdapterFactoryChange(oldValue, adapterFactory));
}
+ public void setDiffRelationshipComputer(IDiffRelationshipComputer diffRelationshipComputer) {
+ IDiffRelationshipComputer oldValue = getDiffRelationshipComputer();
+ setProperty(DIFF_RELATIONSHIP_COMPUTER, diffRelationshipComputer);
+ getEventBus().post(new DiffRelationshipComputerChange(oldValue, diffRelationshipComputer));
+ }
+
private class PropertyChangeListener implements IPropertyChangeListener {
public void propertyChange(PropertyChangeEvent event) {
fireChange(event.getProperty(), event.getOldValue(), event.getNewValue());
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/AdditiveResourceMappingMerger.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/AdditiveResourceMappingMerger.java
index 53f2866f2..dde9c88e5 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/AdditiveResourceMappingMerger.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/AdditiveResourceMappingMerger.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016, 2017 Obeo.
+ * Copyright (c) 2016, 2017 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
* Martin Fleck - bug 512562
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.logical;
@@ -60,6 +61,7 @@ import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
import org.eclipse.emf.compare.ide.utils.ResourceUtil;
import org.eclipse.emf.compare.internal.utils.DiffUtil;
import org.eclipse.emf.compare.merge.AdditiveMergeCriterion;
+import org.eclipse.emf.compare.merge.CachingDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.ComputeDiffsToMerge;
import org.eclipse.emf.compare.merge.DelegatingMerger;
import org.eclipse.emf.compare.merge.MergeBlockedByConflictException;
@@ -111,11 +113,14 @@ public class AdditiveResourceMappingMerger extends EMFResourceMappingMerger impl
private Set<URI> performPreMerge(Comparison comparison, SubMonitor subMonitor) {
final Monitor emfMonitor = BasicMonitor.toMonitor(subMonitor);
final Set<URI> conflictingURIs = new LinkedHashSet<URI>();
- ComputeDiffsToMerge computer = new ComputeDiffsToMerge(true, MERGER_REGISTRY,
- AdditiveMergeCriterion.INSTANCE).failOnRealConflictUnless(isAdditiveConflict());
+ CachingDiffRelationshipComputer relationshipComputer = new CachingDiffRelationshipComputer(
+ MERGER_REGISTRY, AdditiveMergeCriterion.INSTANCE);
+ ComputeDiffsToMerge computer = new ComputeDiffsToMerge(true, relationshipComputer)
+ .failOnRealConflictUnless(isAdditiveConflict());
for (Diff next : comparison.getDifferences()) {
doMergeForDiff(next, computer, emfMonitor, conflictingURIs);
}
+ relationshipComputer.invalidate();
return conflictingURIs;
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java
index 788272b53..2078dcc17 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/logical/EMFResourceMappingMerger.java
@@ -11,6 +11,7 @@
* Alexandra Buzila - bugs 470332, 478620
* Stefan Dirix - bug 507050
* Martin Fleck - bug 512562, 514382
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.logical;
@@ -76,8 +77,10 @@ import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
import org.eclipse.emf.compare.ide.utils.ResourceUtil;
import org.eclipse.emf.compare.ide.utils.StorageTraversal;
import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.CachingDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.ComputeDiffsToMerge;
import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.merge.IMerger.Registry2;
import org.eclipse.emf.compare.merge.MergeBlockedByConflictException;
@@ -325,15 +328,19 @@ public class EMFResourceMappingMerger implements IResourceMappingMerger {
*/
private Set<URI> performPreMerge(Comparison comparison, SubMonitor subMonitor) {
final Monitor emfMonitor = BasicMonitor.toMonitor(subMonitor);
+ final CachingDiffRelationshipComputer relationshipComputer = new CachingDiffRelationshipComputer(
+ MERGER_REGISTRY);
final Set<URI> conflictingURIs = new LinkedHashSet<URI>();
for (Diff next : filter(comparison.getDifferences(), fromSide(DifferenceSource.RIGHT))) {
- doMergeForDiff(emfMonitor, conflictingURIs, next);
+ doMergeForDiff(emfMonitor, conflictingURIs, next, relationshipComputer);
}
+ relationshipComputer.invalidate();
return conflictingURIs;
}
- protected void doMergeForDiff(Monitor emfMonitor, Set<URI> conflictingURIs, Diff diff) {
- ComputeDiffsToMerge computer = new ComputeDiffsToMerge(true, MERGER_REGISTRY)
+ protected void doMergeForDiff(Monitor emfMonitor, Set<URI> conflictingURIs, Diff diff,
+ IDiffRelationshipComputer relationshipComputer) {
+ ComputeDiffsToMerge computer = new ComputeDiffsToMerge(true, relationshipComputer)
.failOnRealConflictUnless(alwaysFalse());
try {
Set<Diff> diffsToMerge = computer.getAllDiffsToMerge(diff);
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DependencyData.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DependencyData.java
index 59d98d29c..2ad486ebe 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DependencyData.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DependencyData.java
@@ -8,6 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
* Martin Fleck - bug 514767
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
@@ -27,8 +28,9 @@ import java.util.List;
import java.util.Set;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.internal.merge.MergeDependenciesUtil;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
@@ -55,6 +57,24 @@ public class DependencyData {
}
/**
+ * Returns the diff relationship computer instance from the compare configuration with the given merger
+ * registry. If no computer instance has been set, a default instance will be created.
+ *
+ * @param mergerRegistry
+ * merger registry used to compute diff relationships.
+ * @return a non-null diff relationship computer.
+ */
+ protected IDiffRelationshipComputer getDiffRelationshipComputer(IMerger.Registry mergerRegistry) {
+ if (compareConfiguration == null || compareConfiguration.getDiffRelationshipComputer() == null) {
+ return new DiffRelationshipComputer(mergerRegistry);
+ }
+ IDiffRelationshipComputer diffRelationshipComputer = compareConfiguration
+ .getDiffRelationshipComputer();
+ diffRelationshipComputer.setMergerRegistry(mergerRegistry);
+ return diffRelationshipComputer;
+ }
+
+ /**
* @param selection
*/
public void updateDependencies(ISelection selection, IMerger.Registry mergerRegistry) {
@@ -69,11 +89,10 @@ public class DependencyData {
rejectedDiffs = newHashSet();
for (Diff diff : selectedDiffs) {
boolean leftToRight = mergePreviewMode.isLeftToRight(diff, leftEditable, rightEditable);
- requires.addAll(
- MergeDependenciesUtil.getAllResultingMerges(diff, mergerRegistry, !leftToRight));
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer(mergerRegistry);
+ requires.addAll(computer.getAllResultingMerges(diff, !leftToRight));
requires.remove(diff);
- rejectedDiffs.addAll(
- MergeDependenciesUtil.getAllResultingRejections(diff, mergerRegistry, !leftToRight));
+ rejectedDiffs.addAll(computer.getAllResultingRejections(diff, !leftToRight));
rejectedDiffs.remove(diff);
requires.removeAll(rejectedDiffs);
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
index 3538a3bac..db93e117e 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
@@ -13,6 +13,7 @@
* Martin Fleck - bug 497066
* Martin Fleck - bug 483798
* Martin Fleck - bug 514767
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
@@ -117,6 +118,7 @@ import org.eclipse.emf.compare.ide.ui.internal.util.PlatformElementUtil;
import org.eclipse.emf.compare.internal.merge.MergeDataImpl;
import org.eclipse.emf.compare.internal.merge.MergeMode;
import org.eclipse.emf.compare.merge.AbstractMerger;
+import org.eclipse.emf.compare.merge.CachingDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMergeOptionAware;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
@@ -240,6 +242,9 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap
/** The adapter factory. */
private ComposedAdapterFactory fAdapterFactory;
+ /** The diff relationship computer. */
+ private CachingDiffRelationshipComputer fDiffRelationshipComputer;
+
/** The tree ruler associated with this viewer. */
private EMFCompareDiffTreeRuler treeRuler;
@@ -579,6 +584,10 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap
fAdapterFactory = initAdapterFactory(getCompareConfiguration().getComparison());
getCompareConfiguration().setAdapterFactory(fAdapterFactory);
+ fDiffRelationshipComputer = new CachingDiffRelationshipComputer(
+ EMFCompareRCPPlugin.getDefault().getMergerRegistry());
+ getCompareConfiguration().setDiffRelationshipComputer(fDiffRelationshipComputer);
+
inputChangedTask = new CompareInputChangedJob(EMFCompareIDEUIMessages
.getString("EMFCompareStructureMergeViewer.computingModelDifferences")); //$NON-NLS-1$
}
@@ -934,6 +943,7 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap
compareInputChanged((ICompareInput)null);
treeRuler.handleDispose();
fAdapterFactory.dispose();
+ fDiffRelationshipComputer.invalidate();
toolBar.dispose();
fColors.dispose();
@@ -1089,6 +1099,11 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap
}
fAdapterFactory = initAdapterFactory(comparison);
+ // clear cache for new comparison
+ if (fDiffRelationshipComputer != null) {
+ fDiffRelationshipComputer.invalidate();
+ }
+
// propagate new adapter factory
config.setAdapterFactory(fAdapterFactory);
getContentProvider().setAdapterFactory(fAdapterFactory);
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractMergeRunnable.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractMergeRunnable.java
index cdec275b8..9c0dd7337 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractMergeRunnable.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractMergeRunnable.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2017 Obeo.
+ * Copyright (c) 2014, 2017 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* Obeo - initial API and implementation
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions;
@@ -21,8 +22,10 @@ import java.util.Collection;
import java.util.Set;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.internal.merge.MergeDependenciesUtil;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.merge.IMerger.Registry;
/**
@@ -31,6 +34,7 @@ import org.eclipse.emf.compare.merge.IMerger.Registry;
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
public abstract class AbstractMergeRunnable {
+
/** Tells us whether the left side of the comparison we're operating on is editable. */
private final boolean isLeftEditable;
@@ -40,6 +44,9 @@ public abstract class AbstractMergeRunnable {
/** Current merging mode. */
private final MergeMode mergeMode;
+ /** Computer to calculate the relationship between diffs. */
+ private IDiffRelationshipComputer diffRelationshipComputer;
+
/**
* Default constructor.
*
@@ -49,11 +56,15 @@ public abstract class AbstractMergeRunnable {
* Whether the right side of the comparison we're operating on is editable.
* @param mergeMode
* Merge mode for this operation.
+ * @param diffRelationshipComputer
+ * The diff relationship computer used to find resulting merges and rejections.
*/
- public AbstractMergeRunnable(boolean isLeftEditable, boolean isRightEditable, MergeMode mergeMode) {
+ public AbstractMergeRunnable(boolean isLeftEditable, boolean isRightEditable, MergeMode mergeMode,
+ IDiffRelationshipComputer diffRelationshipComputer) {
this.isLeftEditable = isLeftEditable;
this.isRightEditable = isRightEditable;
this.mergeMode = mergeMode;
+ this.diffRelationshipComputer = diffRelationshipComputer;
}
protected boolean isLeftEditable() {
@@ -69,6 +80,22 @@ public abstract class AbstractMergeRunnable {
}
/**
+ * Returns the diff relationship computer instance from the compare configuration with the given merger
+ * registry. If no computer instance has been set, a default instance will be created.
+ *
+ * @param mergerRegistry
+ * merger registry used to compute diff relationships.
+ * @return a non-null diff relationship computer.
+ */
+ protected IDiffRelationshipComputer getDiffRelationshipComputer(IMerger.Registry mergerRegistry) {
+ if (diffRelationshipComputer == null) {
+ diffRelationshipComputer = new DiffRelationshipComputer(mergerRegistry);
+ }
+ diffRelationshipComputer.setMergerRegistry(mergerRegistry);
+ return diffRelationshipComputer;
+ }
+
+ /**
* Marks all of the given diffs as merged, keeping track of the merged mode used for the operation.
*
* @param diffToMarkAsMerged
@@ -81,7 +108,7 @@ public abstract class AbstractMergeRunnable {
protected void markAllAsMerged(Collection<? extends Diff> diffToMarkAsMerged, MergeMode mode,
Registry mergerRegistry) {
for (Diff diff : diffToMarkAsMerged) {
- boolean isLeftToRight = mode.isLeftToRight(diff, isLeftEditable, isRightEditable);
+ boolean isLeftToRight = mode.isLeftToRight(diff, isLeftEditable(), isRightEditable());
markAsMerged(diff, mode, !isLeftToRight, mergerRegistry);
}
}
@@ -103,11 +130,10 @@ public abstract class AbstractMergeRunnable {
if (isInTerminalState(diff)) {
return;
}
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer(mergerRegistry);
if (isAccepting(diff, mergeRightToLeft)) {
- final Set<Diff> implied = MergeDependenciesUtil.getAllResultingMerges(diff, mergerRegistry,
- mergeRightToLeft);
- final Set<Diff> rejections = MergeDependenciesUtil.getAllResultingRejections(diff, mergerRegistry,
- mergeRightToLeft);
+ final Set<Diff> implied = computer.getAllResultingMerges(diff, mergeRightToLeft);
+ final Set<Diff> rejections = computer.getAllResultingRejections(diff, mergeRightToLeft);
for (Diff impliedDiff : Sets.difference(implied, rejections)) {
impliedDiff.setState(MERGED);
}
@@ -115,8 +141,7 @@ public abstract class AbstractMergeRunnable {
impliedRejection.setState(DISCARDED);
}
} else {
- final Set<Diff> implied = MergeDependenciesUtil.getAllResultingMerges(diff, mergerRegistry,
- mergeRightToLeft);
+ final Set<Diff> implied = computer.getAllResultingMerges(diff, mergeRightToLeft);
for (Diff impliedDiff : implied) {
impliedDiff.setState(DISCARDED);
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java
index c8b8828f1..9b1c7ac7a 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java
@@ -34,6 +34,7 @@ import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.Navigatable;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.merge.IMerger.Registry;
import org.eclipse.emf.compare.provider.ITooltipLabelProvider;
@@ -81,6 +82,8 @@ public class MergeAction extends BaseSelectionListenerAction {
*/
private AdapterFactory adapterFactory;
+ private IDiffRelationshipComputer diffRelationshipComputer;
+
private boolean isMirrored;
private final boolean isLeftEditable;
@@ -98,6 +101,7 @@ public class MergeAction extends BaseSelectionListenerAction {
super(""); //$NON-NLS-1$
adapterFactory = compareConfiguration.getAdapterFactory();
+ diffRelationshipComputer = compareConfiguration.getDiffRelationshipComputer();
isLeftEditable = compareConfiguration.isLeftEditable();
isRightEditable = compareConfiguration.isRightEditable();
@@ -118,7 +122,8 @@ public class MergeAction extends BaseSelectionListenerAction {
this.editingDomain = compareConfiguration.getEditingDomain();
this.mergerRegistry = mergerRegistry;
this.leftToRight = mode.isLeftToRight(isLeftEditable, isRightEditable);
- this.mergeRunnable = createMergeRunnable(mode, isLeftEditable, isRightEditable);
+ this.mergeRunnable = createMergeRunnable(mode, isLeftEditable, isRightEditable,
+ diffRelationshipComputer);
this.selectedDifferences = newArrayList();
this.selectedMode = mode;
@@ -131,9 +136,9 @@ public class MergeAction extends BaseSelectionListenerAction {
updateSelection(selection);
}
- protected IMergeRunnable createMergeRunnable(MergeMode mode, boolean leftEditable,
- boolean rightEditable) {
- return new MergeRunnableImpl(leftEditable, rightEditable, mode);
+ protected IMergeRunnable createMergeRunnable(MergeMode mode, boolean leftEditable, boolean rightEditable,
+ IDiffRelationshipComputer relationshipComputer) {
+ return new MergeRunnableImpl(leftEditable, rightEditable, mode, relationshipComputer);
}
protected void initToolTipAndImage(MergeMode mode) {
@@ -300,10 +305,12 @@ public class MergeAction extends BaseSelectionListenerAction {
if (mirrored) {
MergeMode mirroredMode = selectedMode.inverse();
leftToRight = mirroredMode.isLeftToRight(isRightEditable, isLeftEditable);
- mergeRunnable = createMergeRunnable(mirroredMode, isRightEditable, isLeftEditable);
+ mergeRunnable = createMergeRunnable(mirroredMode, isRightEditable, isLeftEditable,
+ diffRelationshipComputer);
} else {
leftToRight = selectedMode.isLeftToRight(isLeftEditable, isRightEditable);
- mergeRunnable = createMergeRunnable(selectedMode, isLeftEditable, isRightEditable);
+ mergeRunnable = createMergeRunnable(selectedMode, isLeftEditable, isRightEditable,
+ diffRelationshipComputer);
}
}
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAllNonConflictingAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAllNonConflictingAction.java
index ed8b885ee..16a7e5bd8 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAllNonConflictingAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAllNonConflictingAction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2015 Obeo.
+ * Copyright (c) 2013, 2017 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
* Martin Fleck - bug 514079
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions;
@@ -21,6 +22,7 @@ import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.internal.domain.IMergeAllNonConflictingRunnable;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration;
import org.eclipse.jface.viewers.IStructuredSelection;
@@ -50,8 +52,8 @@ public class MergeAllNonConflictingAction extends MergeAction {
@Override
protected IMergeRunnable createMergeRunnable(MergeMode mode, boolean isLeftEditable,
- boolean isRightEditable) {
- return new MergeNonConflictingRunnable(isLeftEditable, isRightEditable, mode);
+ boolean isRightEditable, IDiffRelationshipComputer relationshipComputer) {
+ return new MergeNonConflictingRunnable(isLeftEditable, isRightEditable, mode, relationshipComputer);
}
@Override
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeContainedNonConflictingAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeContainedNonConflictingAction.java
index 89152d77e..15135fa55 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeContainedNonConflictingAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeContainedNonConflictingAction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 EclipseSource Munich and others.
+ * Copyright (c) 2015, 2017 EclipseSource Munich and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* Philip Langer - initial API and implementation
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions;
@@ -30,6 +31,7 @@ import org.eclipse.emf.compare.domain.IMergeRunnable;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger.Registry;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup;
@@ -124,8 +126,8 @@ public class MergeContainedNonConflictingAction extends MergeAction {
@Override
protected IMergeRunnable createMergeRunnable(MergeMode mode, boolean isLeftEditable,
- boolean isRightEditable) {
- return new MergeNonConflictingRunnable(isLeftEditable, isRightEditable, mode);
+ boolean isRightEditable, IDiffRelationshipComputer relationshipComputer) {
+ return new MergeNonConflictingRunnable(isLeftEditable, isRightEditable, mode, relationshipComputer);
}
@Override
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeNonConflictingRunnable.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeNonConflictingRunnable.java
index de5972c33..445f45294 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeNonConflictingRunnable.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeNonConflictingRunnable.java
@@ -9,6 +9,7 @@
* Obeo - initial API and implementation
* Philip Langer - bug 469355, bug 462884, refactorings
* Martin Fleck - bug 507177
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions;
@@ -53,9 +54,9 @@ import org.eclipse.emf.compare.internal.utils.ComparisonUtil;
import org.eclipse.emf.compare.merge.BatchMerger;
import org.eclipse.emf.compare.merge.ComputeDiffsToMerge;
import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.merge.IMerger.Registry;
-import org.eclipse.emf.compare.merge.IMerger.Registry2;
import org.eclipse.emf.compare.merge.MergeBlockedByConflictException;
/**
@@ -77,9 +78,12 @@ public class MergeNonConflictingRunnable extends AbstractMergeRunnable implement
* Whether the right side of the comparison we're operating on is editable.
* @param mergeMode
* Merge mode for this operation.
+ * @param diffRelationshipComputer
+ * The diff relationship computer used to find resulting merges and rejections.
*/
- public MergeNonConflictingRunnable(boolean isLeftEditable, boolean isRightEditable, MergeMode mergeMode) {
- super(isLeftEditable, isRightEditable, mergeMode);
+ public MergeNonConflictingRunnable(boolean isLeftEditable, boolean isRightEditable, MergeMode mergeMode,
+ IDiffRelationshipComputer diffRelationshipComputer) {
+ super(isLeftEditable, isRightEditable, mergeMode, diffRelationshipComputer);
}
/**
@@ -151,7 +155,7 @@ public class MergeNonConflictingRunnable extends AbstractMergeRunnable implement
private Iterable<Diff> mergeThreeWayWithoutConflicts(Collection<Diff> differences, boolean leftToRight,
Registry mergerRegistry) {
final List<Diff> affectedDiffs;
- final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ final IBatchMerger merger = new BatchMerger(getDiffRelationshipComputer(mergerRegistry));
if (getMergeMode() == MergeMode.LEFT_TO_RIGHT) {
affectedDiffs = Lists
@@ -199,7 +203,7 @@ public class MergeNonConflictingRunnable extends AbstractMergeRunnable implement
private Iterable<Diff> mergeTwoWay(Collection<Diff> differences, boolean leftToRight,
Registry mergerRegistry) {
final List<Diff> affectedDiffs;
- final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ final IBatchMerger merger = new BatchMerger(getDiffRelationshipComputer(mergerRegistry));
// in two-way comparison, difference source is always LEFT
if (getMergeMode() == MergeMode.LEFT_TO_RIGHT) {
@@ -234,8 +238,8 @@ public class MergeNonConflictingRunnable extends AbstractMergeRunnable implement
Registry mergerRegistry) {
final List<Diff> affectedDiffs = new ArrayList<Diff>();
final Monitor emfMonitor = new BasicMonitor();
- ComputeDiffsToMerge computer = new ComputeDiffsToMerge(!leftToRight, (Registry2)mergerRegistry)
- .failOnRealConflictUnless(alwaysFalse());
+ ComputeDiffsToMerge computer = new ComputeDiffsToMerge(!leftToRight,
+ getDiffRelationshipComputer(mergerRegistry)).failOnRealConflictUnless(alwaysFalse());
final Predicate<? super Diff> filter;
if (getMergeMode() == RIGHT_TO_LEFT) {
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeRunnableImpl.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeRunnableImpl.java
index f692550b5..234b7fff6 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeRunnableImpl.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeRunnableImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2017 Obeo.
+ * Copyright (c) 2013, 2017 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* Obeo - initial API and implementation
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions;
@@ -24,6 +25,7 @@ import org.eclipse.emf.compare.internal.merge.MergeMode;
import org.eclipse.emf.compare.internal.merge.MergeOperation;
import org.eclipse.emf.compare.merge.BatchMerger;
import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger.Registry;
/**
@@ -33,8 +35,9 @@ import org.eclipse.emf.compare.merge.IMerger.Registry;
*/
// Visible for testing
public final class MergeRunnableImpl extends AbstractMergeRunnable implements IMergeRunnable {
- public MergeRunnableImpl(boolean isLeftEditable, boolean isRightEditable, MergeMode mergeMode) {
- super(isLeftEditable, isRightEditable, mergeMode);
+ public MergeRunnableImpl(boolean isLeftEditable, boolean isRightEditable, MergeMode mergeMode,
+ IDiffRelationshipComputer diffRelationshipComputer) {
+ super(isLeftEditable, isRightEditable, mergeMode, diffRelationshipComputer);
}
public void merge(List<? extends Diff> differences, boolean leftToRight, Registry mergerRegistry) {
@@ -70,7 +73,7 @@ public final class MergeRunnableImpl extends AbstractMergeRunnable implements IM
private void mergeAll(Collection<? extends Diff> differences, boolean leftToRight,
Registry mergerRegistry) {
- final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ final IBatchMerger merger = new BatchMerger(getDiffRelationshipComputer(mergerRegistry));
if (leftToRight) {
merger.copyAllLeftToRight(differences, new BasicMonitor());
} else {
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java
new file mode 100644
index 000000000..05ea62926
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.internal.configuration;
+
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
+import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent;
+
+/**
+ * Event indicating a change in {@link IDiffRelationshipComputer}.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+public interface IDiffRelationshipComputerChange extends ICompareEvent {
+
+ /**
+ * Previous value of the {@link IDiffRelationshipComputer}.
+ *
+ * @return previous value of the {@link IDiffRelationshipComputer}.
+ */
+ IDiffRelationshipComputer getOldValue();
+
+ /**
+ * New value of the {@link IDiffRelationshipComputer}.
+ *
+ * @return new value of the {@link IDiffRelationshipComputer}.
+ */
+ IDiffRelationshipComputer getNewValue();
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java
index c14d27b6a..6beff7ef5 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java
@@ -17,6 +17,7 @@ import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.StructureMergeViewerGrouper;
import org.eclipse.emf.compare.scope.IComparisonScope;
@@ -58,5 +59,9 @@ public interface IEMFCompareConfiguration {
void setMergePreviewMode(MergeMode mergePreviewMode);
+ IDiffRelationshipComputer getDiffRelationshipComputer();
+
+ void setDiffRelationshipComputer(IDiffRelationshipComputer diffRelationshipComputer);
+
boolean getBooleanProperty(String key, boolean dflt);
}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java
new file mode 100644
index 000000000..302f47da3
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.internal.configuration.impl;
+
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
+import org.eclipse.emf.compare.rcp.ui.internal.configuration.IDiffRelationshipComputerChange;
+
+/**
+ * A change for {@link IDiffRelationshipComputer}.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+public class DiffRelationshipComputerChange extends CompareEvent<IDiffRelationshipComputer> implements IDiffRelationshipComputerChange {
+ public DiffRelationshipComputerChange(IDiffRelationshipComputer oldValue,
+ IDiffRelationshipComputer newValue) {
+ super(oldValue, newValue);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/checkers/MergeDependenciesChecker.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/checkers/MergeDependenciesChecker.java
index 872a55dcb..e0e6d4055 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/checkers/MergeDependenciesChecker.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/checkers/MergeDependenciesChecker.java
@@ -7,10 +7,10 @@ import com.google.common.collect.Sets;
import java.util.Set;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.internal.merge.MergeDependenciesUtil;
+import org.eclipse.emf.compare.merge.DiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
import org.eclipse.emf.compare.merge.IMerger;
-@SuppressWarnings("restriction")
public class MergeDependenciesChecker {
private IMerger.Registry registry;
@@ -58,10 +58,9 @@ public class MergeDependenciesChecker {
}
public void check() {
- Set<Diff> allResultingMerges = MergeDependenciesUtil.getAllResultingMerges(diff, registry,
- this.rightToLeft);
- Set<Diff> allResultingRejections = MergeDependenciesUtil.getAllResultingRejections(diff, registry,
- this.rightToLeft);
+ IDiffRelationshipComputer computer = new DiffRelationshipComputer(registry);
+ Set<Diff> allResultingMerges = computer.getAllResultingMerges(diff, this.rightToLeft);
+ Set<Diff> allResultingRejections = computer.getAllResultingRejections(diff, this.rightToLeft);
assertEquals(this.nbMerges, Sets.difference(allResultingMerges, allResultingRejections).size());
assertEquals(this.nbRejections, allResultingRejections.size());
}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java
new file mode 100644
index 000000000..252f30c3a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.diff;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.internal.spec.DiffSpec;
+import org.eclipse.emf.compare.merge.CachingDiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.ComputeDiffsToMerge;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.merge.IMerger.Registry2;
+import org.eclipse.emf.compare.merge.IMerger2;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This class holds test cases that are related to the {@link IDiffRelationshipComputer} and specifically, the
+ * {@link CachingDiffRelationshipComputer}.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+@SuppressWarnings({"boxing" })
+public class DiffRelationshipComputerTest {
+
+ /** Merge direction. */
+ protected static boolean MERGE_RIGHT_TO_LEFT = true;
+
+ /** Merger registry with the mock merger. */
+ protected Registry2 mergerRegistry;
+
+ /** Mock merger with a high ranking applying to the testing diff. */
+ protected IMerger2 merger;
+
+ /** Comparison. */
+ protected Comparison comparison;
+
+ /** Match. */
+ protected Match match;
+
+ /** Testing diff. */
+ protected Diff diff;
+
+ /** Dependency of the testing diff. */
+ protected Diff mergeDependency;
+
+ /** Resulting diff of the testing diff. */
+ protected Diff resultingMerge;
+
+ /** Resulting rejection of the testing diff. */
+ protected Diff resultingRejection;
+
+ /**
+ * Creates a new merger registry, merger and relevant diffs.
+ */
+ @Before
+ public void setupClass() {
+ mergerRegistry = createMergerRegistry();
+ comparison = createComparison();
+ comparison.getMatches().add(match = createMatch());
+ comparison.getDifferences().add(diff = createDiff(match));
+ comparison.getDifferences().add(mergeDependency = createDiff(match));
+ comparison.getDifferences().add(resultingMerge = createDiff(match));
+ comparison.getDifferences().add(resultingRejection = createDiff(match));
+ merger = mockMerger(diff, mergeDependency, resultingMerge, resultingRejection, 1000, mergerRegistry);
+ mergerRegistry.add(merger);
+ }
+
+ protected CachingDiffRelationshipComputer getDiffRelationshipComputer() {
+ return new CachingDiffRelationshipComputer(mergerRegistry);
+ }
+
+ /**
+ * Tests that the computer is working correctly for direct merge dependencies.
+ */
+ @Test
+ public void testDirectMergeDependencies() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called exactly once
+ verifyDirectMergeDependenciesCalledExactly(1);
+ }
+
+ /**
+ * Tests that the computer is working correctly for direct resulting merges.
+ */
+ @Test
+ public void testDirectResultingMerges() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called exactly once
+ verifyDirectResultingMergesCalledExactly(1);
+ }
+
+ /**
+ * Tests that the computer is working correctly for direct resulting rejections.
+ */
+ @Test
+ public void testDirectResultingRejections() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called exactly once
+ verifyDirectResultingRejectionsCalledExactly(1);
+ }
+
+ /**
+ * Tests that the computer is working correctly for all resulting merges.
+ */
+ @Test
+ public void testAllResultingMerges() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods of the diffs are called at most once
+ verifyMergerCalculationsCalledAtMostOnce();
+ }
+
+ /**
+ * Tests that the computer is working correctly for all resulting rejections.
+ */
+ @Test
+ public void testAllResultingRejections() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call resulting rejections a few more times
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods of the diffs are called at most once
+ verifyMergerCalculationsCalledAtMostOnce();
+ }
+
+ /**
+ * Tests that a diff state change invalidates the cached relationships and leads to a re-calculation of
+ * the relationships.
+ */
+ @Test
+ public void testInvalidateCache() {
+ CachingDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // trigger first time caching
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation method was called exactly once
+ verifyDirectMergeDependenciesCalledExactly(1);
+
+ // invalidate cache
+ computer.invalidate();
+
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called twice now, because we needed to recalculate the relationships
+ verifyDirectMergeDependenciesCalledExactly(2);
+
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called twice now, same as before
+ verifyDirectMergeDependenciesCalledExactly(2);
+
+ // invalidate cache
+ computer.invalidate();
+
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called three times now, because of recalculation
+ verifyDirectMergeDependenciesCalledExactly(3);
+ }
+
+ /**
+ * Tests that the is correctly used in {@link ComputeDiffsToMerge}.
+ */
+ @Test
+ public void testComputeDiffsToMergeIntegration() {
+ ComputeDiffsToMerge computer = new ComputeDiffsToMerge(MERGE_RIGHT_TO_LEFT,
+ new CachingDiffRelationshipComputer(mergerRegistry));
+
+ // call resulting merges a few more times
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+
+ // the calculation methods of the diffs are called at most once
+ verifyMergerCalculationsCalledAtMostOnce();
+ }
+
+ /**
+ * Verifies that any of the relationship calculating methods of the merger were called at most once.
+ */
+ protected void verifyMergerCalculationsCalledAtMostOnce() {
+ verify(merger, atMost(1)).getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT);
+ verify(merger, atMost(1)).getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT);
+ verify(merger, atMost(1)).getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Verifies that the calculation method for the direct merge dependencies was called exactly the given
+ * number of times.
+ *
+ * @param times
+ * number of times the method should have been called.
+ */
+ protected void verifyDirectMergeDependenciesCalledExactly(int times) {
+ verify(merger, times(times)).getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Verifies that the calculation method for the direct resulting merges was called exactly the given
+ * number of times.
+ *
+ * @param times
+ * number of times the method should have been called.
+ */
+ protected void verifyDirectResultingMergesCalledExactly(int times) {
+ verify(merger, times(times)).getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Verifies that the calculation method for the direct resulting rejections was called exactly the given
+ * number of times.
+ *
+ * @param times
+ * number of times the method should have been called.
+ */
+ protected void verifyDirectResultingRejectionsCalledExactly(int times) {
+ verify(merger, times(times)).getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertDirectMergeDependencies(Set<Diff> mergeDependencies) {
+ assertEquals(1, mergeDependencies.size());
+ assertTrue(mergeDependencies.contains(mergeDependency));
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertDirectResultingRejections(Set<Diff> resultingRejections) {
+ assertEquals(1, resultingRejections.size());
+ assertTrue(resultingRejections.contains(resultingRejection));
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertDirectResultingMerges(Set<Diff> resultingMerges) {
+ assertEquals(1, resultingMerges.size());
+ assertTrue(resultingMerges.contains(resultingMerge));
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertAllResultingMerges(Set<Diff> resultingMerges) {
+ assertEquals(3, resultingMerges.size());
+ assertTrue(resultingMerges.contains(mergeDependency));
+ assertTrue(resultingMerges.contains(diff));
+ assertTrue(resultingMerges.contains(resultingMerge));
+ }
+
+ /**
+ * Asserts that the known resulting rejection is the only diff available in the given set.
+ *
+ * @param resultingRejections
+ * calculated resulting rejections
+ */
+ protected void assertAllResultingRejections(Set<Diff> resultingRejections) {
+ assertEquals(1, resultingRejections.size());
+ assertTrue(resultingRejections.contains(resultingRejection));
+ }
+
+ /**
+ * Creates a new comparison.
+ *
+ * @return new comparison instance
+ */
+ private static Comparison createComparison() {
+ return CompareFactory.eINSTANCE.createComparison();
+ }
+
+ /**
+ * Creates a new match.
+ *
+ * @return new match instance
+ */
+ private static Match createMatch() {
+ return CompareFactory.eINSTANCE.createMatch();
+ }
+
+ /**
+ * Creates a new diff instance.
+ *
+ * @param match
+ * @return new diff instance
+ */
+ private static Diff createDiff(Match match) {
+ Diff diff = new DiffSpec();
+ diff.setMatch(match);
+ return diff;
+ }
+
+ /**
+ * Creates a new standalone instance of a merger registry.
+ *
+ * @return new merger registry instance
+ */
+ private static IMerger.Registry2 createMergerRegistry() {
+ return (Registry2)IMerger.RegistryImpl.createStandaloneInstance();
+ }
+
+ /**
+ * Creates a mock merger that returns the given diffs as relationships for the testing diff.
+ *
+ * @param diff
+ * testing diff
+ * @param mergeDependency
+ * dependency of the testing diff
+ * @param resultingMerge
+ * resulting diff for the testing diff
+ * @param resultingRejection
+ * resulting rejection for the testing diff
+ * @param ranking
+ * ranking of the mock merger
+ * @param registry
+ * registry of the mock merger
+ * @return a mock merger
+ */
+ private static IMerger2 mockMerger(Diff diff, Diff mergeDependency, Diff resultingMerge,
+ Diff resultingRejection, int ranking, IMerger.Registry registry) {
+ IMerger2 mockMerger = mock(IMerger2.class);
+ when(mockMerger.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT))
+ .thenReturn(Sets.newHashSet(mergeDependency));
+ when(mockMerger.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT))
+ .thenReturn(Sets.newHashSet(resultingMerge));
+ when(mockMerger.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT))
+ .thenReturn(Sets.newHashSet(resultingRejection));
+ when(mockMerger.isMergerFor(any(Diff.class))).thenReturn(Boolean.TRUE);
+ when(mockMerger.getRanking()).thenReturn(ranking);
+ when(mockMerger.getRegistry()).thenReturn(registry);
+ return mockMerger;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
index a69af8112..21a233f10 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
@@ -11,6 +11,7 @@
* Stefan Dirix - Adds additional test classes
* Michael Borkowski - Adds additional test classes
* Martin Fleck - Add ImplicationMergeTest, GraphTest
+ * Martin Fleck - Add DiffCacheAdapterTest
*******************************************************************************/
package org.eclipse.emf.compare.tests.suite;
@@ -22,6 +23,7 @@ import org.eclipse.emf.compare.tests.conflict.MultiLineAttributeConflictDetectio
import org.eclipse.emf.compare.tests.conflict.PseudoConflictDetectionTest;
import org.eclipse.emf.compare.tests.conflict.data.bug484557.Bug484557ConflictTest;
import org.eclipse.emf.compare.tests.diff.ComparisonUtilTest;
+import org.eclipse.emf.compare.tests.diff.DiffRelationshipComputerTest;
import org.eclipse.emf.compare.tests.diff.DiffUtilTest;
import org.eclipse.emf.compare.tests.diff.FeatureFilterTest;
import org.eclipse.emf.compare.tests.diff.FeatureMapMoveDiffTest;
@@ -108,7 +110,7 @@ import junit.textui.TestRunner;
RankedAdapterFactoryRegistryTest.class, ComparisonScopeAdapterTest.class,
EMFComparePredicatesTest.class, ImplicationsMergeTest.class, GraphTest.class,
ConflictImplicationsTest_Bug484579.class, PseudoConflictDetectionTest.class, ComplexMergeTest.class,
- ConflictSearchTest.class, })
+ ConflictSearchTest.class, DiffRelationshipComputerTest.class })
public class AllTests {
/**
* Standalone launcher for all of compare's tests.
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java
deleted file mode 100644
index ed5285634..000000000
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014, 2016 Obeo and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- * Philip Langer - bug 462884
- * Martin Fleck - bug 507177
- *******************************************************************************/
-package org.eclipse.emf.compare.internal.merge;
-
-import static com.google.common.base.Predicates.and;
-import static com.google.common.base.Predicates.not;
-import static org.eclipse.emf.compare.ConflictKind.PSEUDO;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.sameSideAs;
-
-import com.google.common.collect.Sets;
-import com.google.common.collect.Sets.SetView;
-
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.merge.IMerger;
-import org.eclipse.emf.compare.merge.IMerger2;
-
-/**
- * Factorizes utilities used throughout EMF Compare to explore merge dependencies.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public final class MergeDependenciesUtil {
- /** Hides default constructor. */
- private MergeDependenciesUtil() {
- // Hides default constructor
- }
-
- /**
- * Retrieves the set of all diffs related to the given <code>diff</code> when merging in the given
- * direction.
- * <p>
- * This is expected to return the set of all differences that will be need to merged along when a user
- * wishes to merge <code>diff</code>, either because they are required by it or because they are implied
- * by it one way or another.
- * </p>
- * <p>
- * Note that <code>diff</code> will be included in the returned set.
- * </p>
- * <p>
- * Also note that the resulting merges will contain the resulting rejections (diffs from the other side
- * that will be rejected)
- * </p>
- *
- * @param diff
- * The difference for which we seek all related ones.
- * @param mergerRegistry
- * The {@link IMerger.Registry merger registry} currently in use.
- * @param rightToLeft
- * The direction in which we're considering a merge.
- * @return The set of all diffs related to the given <code>diff</code> when merging in the given
- * direction.
- */
- public static Set<Diff> getAllResultingMerges(Diff diff, IMerger.Registry mergerRegistry,
- boolean rightToLeft) {
- final Set<Diff> resultingMerges = new LinkedHashSet<Diff>();
- resultingMerges.add(diff);
-
- Set<Diff> relations = internalGetResultingMerges(diff, mergerRegistry, rightToLeft);
- // We don't want to take in account pseudo conflicts since there is nothing to do with them
- // and their dependencies may cause incorrect merge dependencies computation.
- Set<Diff> difference = Sets.filter(Sets.difference(relations, resultingMerges),
- not(hasConflict(PSEUDO)));
- while (!difference.isEmpty()) {
- final Set<Diff> newRelations = new LinkedHashSet<Diff>(difference);
- resultingMerges.addAll(newRelations);
- relations = new LinkedHashSet<Diff>();
- for (Diff newRelation : newRelations) {
- Set<Diff> internalResultingMerges = internalGetResultingMerges(newRelation, mergerRegistry,
- rightToLeft);
- // We don't want to take in account pseudo conflicts since there is nothing to do with them
- // and there dependencies may cause incorrect merge dependencies computation.
- relations.addAll(Sets.filter(internalResultingMerges, not(hasConflict(PSEUDO))));
- }
- difference = Sets.difference(relations, resultingMerges);
- }
-
- // If a pseudo conflict is directly selected, we want to display other diffs of the pseudo conflict as
- // resulting merge for the user
- if (diff.getConflict() != null && diff.getConflict().getKind() == PSEUDO) {
- resultingMerges.addAll(diff.getConflict().getDifferences());
- }
-
- return resultingMerges;
- }
-
- /**
- * Returns the set of all differences <b>directly</b> related to the given one, either as dependencies or
- * as implications.
- *
- * @param diff
- * The difference for which we seek all directly related others.
- * @param mergerRegistry
- * The {@link IMerger.Registry merger registry} currently in use.
- * @param rightToLeft
- * The direction in which we're considering a merge.
- * @return The set of all differences <b>directly</b> related to the given one.
- */
- private static Set<Diff> internalGetResultingMerges(Diff diff, IMerger.Registry mergerRegistry,
- boolean rightToLeft) {
- final IMerger merger = mergerRegistry.getHighestRankingMerger(diff);
- final Set<Diff> directParents;
- final Set<Diff> directImplications;
- if (merger instanceof IMerger2) {
- directParents = ((IMerger2)merger).getDirectMergeDependencies(diff, rightToLeft);
- directImplications = ((IMerger2)merger).getDirectResultingMerges(diff, rightToLeft);
- } else {
- directParents = Collections.emptySet();
- directImplications = Collections.emptySet();
- }
-
- final SetView<Diff> directRelated = Sets.union(directParents, directImplications);
-
- return directRelated;
- }
-
- /**
- * Retrieves the set of all diffs that will be rejected if the given <code>diff</code> is merged, either
- * because of unresolveable conflicts or because of unreachable requirements.
- *
- * @param diff
- * The difference for which we seek all opposite ones.
- * @param mergerRegistry
- * The {@link IMerger.Registry merger registry} currently in use.
- * @param mergeRightToLeft
- * The direction in which we're considering a merge.
- * @return The set of all diffs that will be rejected if the given <code>diff</code> is merged in the
- * given direction.
- */
- public static Set<Diff> getAllResultingRejections(Diff diff, IMerger.Registry mergerRegistry,
- boolean mergeRightToLeft) {
- final Set<Diff> resultingRejections = new LinkedHashSet<Diff>();
-
- final Set<Diff> allResultingMerges = getAllResultingMerges(diff, mergerRegistry, mergeRightToLeft);
- resultingRejections.addAll(
- Sets.filter(allResultingMerges, and(not(hasConflict(PSEUDO)), not(sameSideAs(diff)))));
- // Only search rejections caused by diffs on the same side
- for (Diff resulting : Sets.filter(allResultingMerges, sameSideAs(diff))) {
- Set<Diff> rejections = internalGetResultingRejections(resulting, mergerRegistry,
- mergeRightToLeft);
- // We don't want to take in account pseudo conflicts since there is nothing to do with them
- // and their dependencies may cause incorrect merge dependencies computation.
- Set<Diff> difference = Sets.filter(rejections, not(hasConflict(PSEUDO)));
- while (!difference.isEmpty()) {
- final Set<Diff> newRejections = new LinkedHashSet<Diff>(difference);
- resultingRejections.addAll(newRejections);
- rejections = new LinkedHashSet<Diff>();
- for (Diff rejected : newRejections) {
- final IMerger merger = mergerRegistry.getHighestRankingMerger(rejected);
- if (merger instanceof IMerger2) {
- Set<Diff> directMergeDependencies = ((IMerger2)merger)
- .getDirectMergeDependencies(rejected, mergeRightToLeft);
- // We don't want to take in account pseudo conflicts since there is nothing to do with
- // them and their dependencies may cause incorrect merge dependencies computation.
- // We also don't want to consider diffs on the same side for rejections
- rejections.addAll(Sets.filter(directMergeDependencies,
- and(not(hasConflict(PSEUDO)), not(sameSideAs(diff)))));
- Set<Diff> directResultingMerges = ((IMerger2)merger)
- .getDirectResultingMerges(rejected, mergeRightToLeft);
- rejections.addAll(Sets.filter(directResultingMerges,
- and(not(hasConflict(PSEUDO)), not(sameSideAs(diff)))));
- }
- }
- difference = Sets.difference(rejections, resultingRejections);
- }
- }
- return resultingRejections;
- }
-
- /**
- * Returns the set of differences directly related to <code>diff</code> that will be rejected if it is
- * merged.
- *
- * @param diff
- * The difference for which we seek all opposite ones.
- * @param mergerRegistry
- * The {@link IMerger.Registry merger registry} currently in use.
- * @param rightToLeft
- * The direction in which we're considering a merge.
- * @return The set of all directly related differences that will be rejected if <code>diff</code> is
- * merged in the given direction.
- */
- private static Set<Diff> internalGetResultingRejections(Diff diff, IMerger.Registry mergerRegistry,
- boolean rightToLeft) {
- final IMerger merger = mergerRegistry.getHighestRankingMerger(diff);
- if (merger instanceof IMerger2) {
- return ((IMerger2)merger).getDirectResultingRejections(diff, rightToLeft);
- }
- return Collections.emptySet();
- }
-}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java
index b49795edd..f129cc3de 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java
@@ -40,6 +40,9 @@ public class BatchMerger implements IBatchMerger {
/** Filter the differences that should be merged. */
private final Predicate<? super Diff> filter;
+ /** The relationship computer used to calculate dependencies and requirements of diffs. */
+ private IDiffRelationshipComputer relationshipComputer;
+
/**
* Constructs our batch merger provided the registry from which to retrieve the delegate mergers. Using
* such a merger will merge every differences passed to its "copy" methods : conflictual or not.
@@ -49,7 +52,19 @@ public class BatchMerger implements IBatchMerger {
* IMerger.Registry2.
*/
public BatchMerger(IMerger.Registry registry) {
- this(registry, alwaysTrue());
+ this(new DiffRelationshipComputer(registry), alwaysTrue());
+ }
+
+ /**
+ * Constructs our batch merger provided the registry from which to retrieve the delegate mergers. Using
+ * such a merger will merge every differences passed to its "copy" methods : conflictual or not.
+ *
+ * @param relationshipComputer
+ * The relationship computer used to calculate dependencies and requirements of diffs.
+ * @since 3.5
+ */
+ public BatchMerger(IDiffRelationshipComputer relationshipComputer) {
+ this(relationshipComputer, alwaysTrue());
}
/**
@@ -79,7 +94,38 @@ public class BatchMerger implements IBatchMerger {
* @see org.eclipse.emf.compare.utils.EMFComparePredicates
*/
public BatchMerger(IMerger.Registry registry, Predicate<? super Diff> filter) {
- this.registry = (IMerger.Registry2)checkNotNull(registry);
+ this(new DiffRelationshipComputer(registry), filter);
+ }
+
+ /**
+ * Constructs our batch merger provided the registry from which to retrieve the delegate mergers, and a
+ * filter if you only wish to merge specific differences.
+ * <p>
+ * <b>Note</b> that the filter indicates differences that will be merged, not those that will be ignored.
+ * </p>
+ * <p>
+ * For example, if you wish to ignore all differences in conflict, you can use :
+ *
+ * <pre>
+ * IMerger.Registry registry = IMerger.RegistryImpl.createStandaloneInstance();
+ * IBatchMerger bathMerger = new BatchMerger(registry, {@link com.google.common.base.Predicates#not(Predicate) not}({@link org.eclipse.emf.compare.utils.EMFComparePredicates#hasConflict(org.eclipse.emf.compare.ConflictKind...) hasConflict}(ConflictKind.PSEUDO, ConflictKind.REAL)));
+ * bathMerger.copyAll...
+ * </pre>
+ * </p>
+ *
+ * @param filter
+ * Additional filter for the differences. This could be set in order to ignore diffs
+ * originating from a given side. Note that the filter describes the differences that will be
+ * merged, not those that will be ignored.
+ * @param relationshipComputer
+ * The relationship computer used to calculate dependencies and requirements of diffs.
+ * @see com.google.common.base.Predicates
+ * @see org.eclipse.emf.compare.utils.EMFComparePredicates
+ * @since 3.5
+ */
+ public BatchMerger(IDiffRelationshipComputer relationshipComputer, Predicate<? super Diff> filter) {
+ this.relationshipComputer = checkNotNull(relationshipComputer);
+ this.registry = (IMerger.Registry2)checkNotNull(relationshipComputer.getMergerRegistry());
this.filter = checkNotNull(filter);
}
@@ -95,7 +141,7 @@ public class BatchMerger implements IBatchMerger {
start = System.currentTimeMillis();
LOGGER.debug("copyAllLeftToRight(differences, monitor) - Start"); //$NON-NLS-1$
}
- ComputeDiffsToMerge computer = new ComputeDiffsToMerge(false, registry);
+ ComputeDiffsToMerge computer = new ComputeDiffsToMerge(false, relationshipComputer);
for (Diff diff : Iterables.filter(differences, filter)) {
if (!AbstractMerger.isInTerminalState(diff)) {
Set<Diff> diffsToMerge = computer.getAllDiffsToMerge(diff);
@@ -129,7 +175,7 @@ public class BatchMerger implements IBatchMerger {
start = System.currentTimeMillis();
LOGGER.debug("copyAllRightToLeft(differences, monitor) - Start"); //$NON-NLS-1$
}
- ComputeDiffsToMerge computer = new ComputeDiffsToMerge(true, registry);
+ ComputeDiffsToMerge computer = new ComputeDiffsToMerge(true, relationshipComputer);
for (Diff diff : Iterables.filter(differences, filter)) {
if (!AbstractMerger.isInTerminalState(diff)) {
Set<Diff> diffsToMerge = computer.getAllDiffsToMerge(diff);
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/CachingDiffRelationshipComputer.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/CachingDiffRelationshipComputer.java
new file mode 100644
index 000000000..64bdc7734
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/CachingDiffRelationshipComputer.java
@@ -0,0 +1,524 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.merge;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.merge.IMerger.Registry;
+
+/**
+ * A computer implementation to cache the relationship of diffs.
+ *
+ * @since 3.5
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ * @see IMerger2
+ */
+public class CachingDiffRelationshipComputer implements IDiffRelationshipComputer {
+
+ /** A computer instance to calculate the relationships between diffs. */
+ protected IDiffRelationshipComputer computer;
+
+ /** Direct merge dependencies: right to left. */
+ protected Map<Diff, Set<Diff>> directMergeDependenciesR2L = new ConcurrentHashMap<>();
+
+ /** Direct merge dependencies: left to right. */
+ protected Map<Diff, Set<Diff>> directMergeDependenciesL2R = new ConcurrentHashMap<>();
+
+ /** Direct resulting merges: right to left. */
+ protected Map<Diff, Set<Diff>> directResultingMergesR2L = new ConcurrentHashMap<>();
+
+ /** Direct resulting merges: left to right. */
+ protected Map<Diff, Set<Diff>> directResultingMergesL2R = new ConcurrentHashMap<>();
+
+ /** Direct resulting rejections: right to left. */
+ protected Map<Diff, Set<Diff>> directResultingRejectionsR2L = new ConcurrentHashMap<>();
+
+ /** Direct resulting rejections: left to right. */
+ protected Map<Diff, Set<Diff>> directResultingRejectionsL2R = new ConcurrentHashMap<>();
+
+ /** All resulting merges: right to left. */
+ protected Map<Diff, Set<Diff>> allResultingMergesR2L = new ConcurrentHashMap<>();
+
+ /** All resulting merges: left to right. */
+ protected Map<Diff, Set<Diff>> allResultingMergesL2R = new ConcurrentHashMap<>();
+
+ /** All resulting rejections: right to left. */
+ protected Map<Diff, Set<Diff>> allResultingRejectionsR2L = new ConcurrentHashMap<>();
+
+ /** All resulting rejections: left to right. */
+ protected Map<Diff, Set<Diff>> allResultingRejectionsL2R = new ConcurrentHashMap<>();
+
+ /**
+ * Creates a new computer with the given registry.
+ *
+ * @param registry
+ * merger registry
+ */
+ public CachingDiffRelationshipComputer(IMerger.Registry registry) {
+ this(registry, IMergeCriterion.NONE);
+ }
+
+ /**
+ * Creates a new computer with the given registry and merge criterion.
+ *
+ * @param registry
+ * merger registry
+ * @param criterion
+ * merge criterion used to get the merger from the registry, use {@link IMergeCriterion#NONE}
+ * if no special criterion should be set.
+ */
+ public CachingDiffRelationshipComputer(IMerger.Registry registry, IMergeCriterion criterion) {
+ this(new DiffRelationshipComputer(registry, criterion));
+ }
+
+ /**
+ * Creates a new computer by wrapping the given instance. Any computing calls are delegated to this
+ * instance and cached.
+ *
+ * @param computer
+ * computer instance used for calculating diff relationships.
+ */
+ public CachingDiffRelationshipComputer(IDiffRelationshipComputer computer) {
+ this.computer = computer;
+ }
+
+ /**
+ * Returns the internal computer instance used to compute the diff relationships.
+ *
+ * @return internal computer instance.
+ */
+ protected IDiffRelationshipComputer getComputer() {
+ return computer;
+ }
+
+ @Override
+ public Registry getMergerRegistry() {
+ return getComputer().getMergerRegistry();
+ }
+
+ /**
+ * {@inheritDoc} WARNING: Setting the merger registry invalidates previously cached results, if another
+ * registry was set previously!
+ */
+ public void setMergerRegistry(Registry mergerRegistry) {
+ if (getMergerRegistry() != mergerRegistry) {
+ getComputer().setMergerRegistry(mergerRegistry);
+ invalidate();
+ }
+ }
+
+ @Override
+ public IMergeCriterion getMergeCriterion() {
+ return getComputer().getMergeCriterion();
+ }
+
+ @Override
+ public IMerger2 getMerger(Diff diff) {
+ return getComputer().getMerger(diff);
+ }
+
+ @Override
+ public boolean hasMerger(Diff diff) {
+ return getComputer().hasMerger(diff);
+ }
+
+ /**
+ * {@inheritDoc} WARNING: Setting the merge criterion invalidates previously cached results, if another
+ * criterion was set previously.
+ */
+ public void setMergeCriterion(IMergeCriterion mergeCriterion) {
+ if (getMergeCriterion() != mergeCriterion) {
+ getComputer().setMergeCriterion(mergeCriterion);
+ invalidate();
+ }
+ }
+
+ /**
+ * Caches the given direct merge dependencies.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @param directMergeDependencies
+ * direct merge dependencies of diff
+ */
+ protected void setCachedDirectMergeDependencies(Diff diff, boolean mergeRightToLeft,
+ Set<Diff> directMergeDependencies) {
+ if (mergeRightToLeft) {
+ directMergeDependenciesR2L.put(diff, directMergeDependencies);
+ } else {
+ directMergeDependenciesL2R.put(diff, directMergeDependencies);
+ }
+ }
+
+ /**
+ * Returns the cached direct merge dependencies.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached direct merge dependencies
+ */
+ protected Set<Diff> getCachedDirectMergeDependencies(Diff diff, boolean mergeRightToLeft) {
+ if (mergeRightToLeft) {
+ return directMergeDependenciesR2L.get(diff);
+ } else {
+ return directMergeDependenciesL2R.get(diff);
+ }
+ }
+
+ /**
+ * Computes direct merge dependencies for the given diff.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return a non-null set of direct merge dependencies
+ */
+ protected Set<Diff> computeDirectMergeDependencies(Diff diff, boolean mergeRightToLeft) {
+ return getComputer().getDirectMergeDependencies(diff, mergeRightToLeft);
+ }
+
+ /**
+ * Returns the cached direct merge dependencies, if present. Otherwise, the direct merge dependencies are
+ * retrieved and cached using the given merger.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached direct merge dependencies
+ * @see IMerger2#getDirectMergeDependencies(Diff, boolean)
+ */
+ @Override
+ public Set<Diff> getDirectMergeDependencies(Diff diff, boolean mergeRightToLeft) {
+ Set<Diff> directMergeDependencies = getCachedDirectMergeDependencies(diff, mergeRightToLeft);
+ if (directMergeDependencies == null) {
+ directMergeDependencies = computeDirectMergeDependencies(diff, mergeRightToLeft);
+ setCachedDirectMergeDependencies(diff, mergeRightToLeft, directMergeDependencies);
+ }
+ return directMergeDependencies;
+ }
+
+ /**
+ * Caches the given direct resulting merges.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @param directResultingMerges
+ * direct resulting merges
+ */
+ protected void setCachedDirectResultingMerges(Diff diff, boolean mergeRightToLeft,
+ Set<Diff> directResultingMerges) {
+ if (mergeRightToLeft) {
+ directResultingMergesR2L.put(diff, directResultingMerges);
+ } else {
+ directResultingMergesL2R.put(diff, directResultingMerges);
+ }
+ }
+
+ /**
+ * Returns the cached direct resulting merges.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached direct resulting merges
+ */
+ protected Set<Diff> getCachedDirectResultingMerges(Diff diff, boolean mergeRightToLeft) {
+ if (mergeRightToLeft) {
+ return directResultingMergesR2L.get(diff);
+ } else {
+ return directResultingMergesL2R.get(diff);
+ }
+ }
+
+ /**
+ * Computes direct resulting merges for the given diff.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return a non-null set of all resulting merges
+ */
+ protected Set<Diff> computeDirectResultingMerges(Diff diff, boolean mergeRightToLeft) {
+ return getComputer().getDirectResultingMerges(diff, mergeRightToLeft);
+ }
+
+ /**
+ * Returns the cached direct resulting merges, if present. Otherwise, the direct resulting merges are
+ * retrieved and cached using the given merger.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached direct resulting merges
+ * @see IMerger2#getDirectResultingMerges(Diff, boolean)
+ */
+ @Override
+ public Set<Diff> getDirectResultingMerges(Diff diff, boolean mergeRightToLeft) {
+ Set<Diff> directResultingMerges = getCachedDirectResultingMerges(diff, mergeRightToLeft);
+ if (directResultingMerges == null) {
+ directResultingMerges = computeDirectResultingMerges(diff, mergeRightToLeft);
+ setCachedDirectResultingMerges(diff, mergeRightToLeft, directResultingMerges);
+ }
+ return directResultingMerges;
+ }
+
+ /**
+ * Caches the given direct resulting rejections.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @param directResultingRejections
+ * direct resulting rejections
+ */
+ protected void setCachedDirectResultingRejections(Diff diff, boolean mergeRightToLeft,
+ Set<Diff> directResultingRejections) {
+ if (mergeRightToLeft) {
+ directResultingRejectionsR2L.put(diff, directResultingRejections);
+ } else {
+ directResultingRejectionsL2R.put(diff, directResultingRejections);
+ }
+ }
+
+ /**
+ * Returns the cached direct resulting rejections.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached direct resulting rejections
+ */
+ protected Set<Diff> getCachedDirectResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ if (mergeRightToLeft) {
+ return directResultingRejectionsR2L.get(diff);
+ } else {
+ return directResultingRejectionsL2R.get(diff);
+ }
+ }
+
+ /**
+ * Computes the direct resulting rejections.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return a non-null set of direct resulting rejections
+ */
+ protected Set<Diff> computeDirectResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ return getComputer().getDirectResultingRejections(diff, mergeRightToLeft);
+ }
+
+ @Override
+ public Set<Diff> getDirectResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ Set<Diff> directResultingRejections = getCachedDirectResultingRejections(diff, mergeRightToLeft);
+ if (directResultingRejections == null) {
+ directResultingRejections = computeDirectResultingRejections(diff, mergeRightToLeft);
+ setCachedDirectResultingRejections(diff, mergeRightToLeft, directResultingRejections);
+ }
+ return directResultingRejections;
+ }
+
+ /**
+ * Caches the given all resulting rejections.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @param allResultingRejections
+ * all resulting rejections
+ */
+ protected void setCachedAllResultingRejections(Diff diff, boolean mergeRightToLeft,
+ Set<Diff> allResultingRejections) {
+ if (mergeRightToLeft) {
+ allResultingRejectionsR2L.put(diff, allResultingRejections);
+ } else {
+ allResultingRejectionsL2R.put(diff, allResultingRejections);
+ }
+ }
+
+ /**
+ * Returns the cached all resulting rejections.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached all resulting rejections
+ */
+ protected Set<Diff> getCachedAllResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ if (mergeRightToLeft) {
+ return allResultingRejectionsR2L.get(diff);
+ } else {
+ return allResultingRejectionsL2R.get(diff);
+ }
+ }
+
+ /**
+ * Computes all resulting rejections for the given diff.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return a non-null set of all resulting rejections
+ */
+ protected Set<Diff> computeAllResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ return getComputer().getAllResultingRejections(diff, mergeRightToLeft);
+ }
+
+ @Override
+ public Set<Diff> getAllResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ Set<Diff> allResultingRejections = getCachedAllResultingRejections(diff, mergeRightToLeft);
+ if (allResultingRejections == null) {
+ allResultingRejections = computeAllResultingRejections(diff, mergeRightToLeft);
+ setCachedAllResultingRejections(diff, mergeRightToLeft, allResultingRejections);
+ }
+ return allResultingRejections;
+ }
+
+ /**
+ * Caches the given all resulting merges.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @param allResultingMerges
+ * all resulting merges
+ */
+ protected void setCachedAllResultingMerges(Diff diff, boolean mergeRightToLeft,
+ Set<Diff> allResultingMerges) {
+ if (mergeRightToLeft) {
+ allResultingMergesR2L.put(diff, allResultingMerges);
+ } else {
+ allResultingMergesL2R.put(diff, allResultingMerges);
+ }
+ }
+
+ /**
+ * Returns the cached all resulting merges.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached all resulting merges
+ */
+ protected Set<Diff> getCachedAllResultingMerges(Diff diff, boolean mergeRightToLeft) {
+ if (mergeRightToLeft) {
+ return allResultingMergesR2L.get(diff);
+ } else {
+ return allResultingMergesL2R.get(diff);
+ }
+ }
+
+ /**
+ * Computes all resulting merges for the given diff.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return a non-null set of all resulting merges
+ */
+ protected Set<Diff> computeAllResultingMerges(Diff diff, boolean mergeRightToLeft) {
+ return getComputer().getAllResultingMerges(diff, mergeRightToLeft);
+ }
+
+ /**
+ * Returns the cached direct resulting merges, if present. Otherwise, the direct resulting merges are
+ * retrieved and cached using the given merger.
+ *
+ * @param diff
+ * diff
+ * @param mergeRightToLeft
+ * merge direction
+ * @return cached direct resulting merges
+ * @see IMerger2#getDirectResultingMerges(Diff, boolean)
+ */
+ @Override
+ public Set<Diff> getAllResultingMerges(Diff diff, boolean mergeRightToLeft) {
+ Set<Diff> allResultingMerges = getCachedAllResultingMerges(diff, mergeRightToLeft);
+ if (allResultingMerges == null) {
+ allResultingMerges = computeAllResultingMerges(diff, mergeRightToLeft);
+ setCachedAllResultingMerges(diff, mergeRightToLeft, allResultingMerges);
+ }
+ return allResultingMerges;
+ }
+
+ /**
+ * Invalidates the cache for the given diff, so that relationships will be re-calculated for this diff the
+ * next time a respective method is called.
+ *
+ * @param diff
+ * diff for which the cache should be invalidated.
+ */
+ public void invalidate(Diff diff) {
+ directMergeDependenciesR2L.remove(diff);
+ directMergeDependenciesL2R.remove(diff);
+ directResultingRejectionsR2L.remove(diff);
+ directResultingRejectionsL2R.remove(diff);
+ directResultingMergesR2L.remove(diff);
+ directResultingMergesL2R.remove(diff);
+ allResultingMergesL2R.remove(diff);
+ allResultingMergesR2L.remove(diff);
+ allResultingRejectionsL2R.remove(diff);
+ allResultingRejectionsR2L.remove(diff);
+ }
+
+ /**
+ * Invalidates the cache for all given diffs, so that relationships will be re-calculated for each diff
+ * the next time a respective method is called.
+ *
+ * @param diffs
+ * diffs for which the cache should be invalidated.
+ */
+ public void invalidate(Iterable<Diff> diffs) {
+ for (Diff diff : diffs) {
+ invalidate(diff);
+ }
+ }
+
+ /**
+ * Invalidates the complete cache, so that relationships will be re-calculated any diff the next time a
+ * respective method is called.
+ */
+ public void invalidate() {
+ directMergeDependenciesR2L.clear();
+ directMergeDependenciesL2R.clear();
+ directResultingRejectionsR2L.clear();
+ directResultingRejectionsL2R.clear();
+ directResultingMergesR2L.clear();
+ directResultingMergesL2R.clear();
+ allResultingMergesL2R.clear();
+ allResultingMergesR2L.clear();
+ allResultingRejectionsL2R.clear();
+ allResultingRejectionsR2L.clear();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ComputeDiffsToMerge.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ComputeDiffsToMerge.java
index 02b569291..c1469d570 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ComputeDiffsToMerge.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ComputeDiffsToMerge.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017 Obeo.
+ * Copyright (c) 2017 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,10 +7,10 @@
*
* Contributors:
* Obeo - initial API and implementation
+ * Martin Fleck - bug 514415
*******************************************************************************/
package org.eclipse.emf.compare.merge;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.eclipse.emf.compare.ConflictKind.REAL;
import static org.eclipse.emf.compare.merge.IMergeCriterion.NONE;
@@ -54,16 +54,6 @@ public class ComputeDiffsToMerge {
private final boolean rightToLeft;
/**
- * The merge criterion to use, can be <code>null</code>.
- */
- private IMergeCriterion criterion;
-
- /**
- * The merger registry to use.
- */
- private IMerger.Registry2 registry;
-
- /**
* The ordered set of diffs to merge.
*/
private Set<Diff> result = new LinkedHashSet<Diff>();
@@ -77,6 +67,9 @@ public class ComputeDiffsToMerge {
*/
private Predicate<? super Conflict> conflictChecker;
+ /** The relationship computer used to calculate dependencies and requirements of diffs. */
+ private IDiffRelationshipComputer relationshipComputer;
+
/**
* Constructor.
*
@@ -86,7 +79,7 @@ public class ComputeDiffsToMerge {
* The Registry to use.
*/
public ComputeDiffsToMerge(boolean rightToLeft, IMerger.Registry2 registry) {
- this(rightToLeft, registry, NONE);
+ this(rightToLeft, new DiffRelationshipComputer(registry, NONE));
}
/**
@@ -100,9 +93,20 @@ public class ComputeDiffsToMerge {
* The merge criterion, must not be <code>null</code>
*/
public ComputeDiffsToMerge(boolean rightToLeft, IMerger.Registry2 registry, IMergeCriterion criterion) {
+ this(rightToLeft, new DiffRelationshipComputer(registry, criterion));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param rightToLeft
+ * The merge direction
+ * @param relationshipComputer
+ * The relationship computer used to calculate dependencies and requirements of diffs.
+ */
+ public ComputeDiffsToMerge(boolean rightToLeft, IDiffRelationshipComputer relationshipComputer) {
this.rightToLeft = rightToLeft;
- this.registry = registry;
- this.criterion = checkNotNull(criterion);
+ this.relationshipComputer = relationshipComputer;
}
/**
@@ -179,16 +183,17 @@ public class ComputeDiffsToMerge {
diffsThatLedToConflict.add(diff);
throw new MergeBlockedByConflictException(diffsThatLedToConflict);
}
- DelegatingMerger mergerDelegate = AbstractMerger.getMergerDelegate(diff, registry, criterion);
- IMerger merger = mergerDelegate.getMerger();
- if (merger instanceof IMerger2) {
- Set<Diff> dependencies = ((IMerger2)merger).getDirectMergeDependencies(diff, rightToLeft);
+
+ if (relationshipComputer.hasMerger(diff)) {
+ Set<Diff> dependencies = relationshipComputer.getDirectMergeDependencies(diff, rightToLeft);
for (Diff required : dependencies) {
addDiff(required, consequences);
}
+
result.add(diff);
computing.remove(diff);
- consequences.addAll(((IMerger2)merger).getDirectResultingMerges(diff, rightToLeft));
+
+ consequences.addAll(relationshipComputer.getDirectResultingMerges(diff, rightToLeft));
} else {
result.add(diff);
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/DiffRelationshipComputer.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/DiffRelationshipComputer.java
new file mode 100644
index 000000000..c144f3b7a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/DiffRelationshipComputer.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.merge;
+
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.not;
+import static org.eclipse.emf.compare.ConflictKind.PSEUDO;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.sameSideAs;
+
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.merge.IMerger.Registry;
+import org.eclipse.emf.compare.merge.IMerger.Registry2;
+
+/**
+ * A computer implementation to calculate the relationship of differences in EMF Compare.
+ *
+ * @since 3.5
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ * @see IMerger2
+ */
+public class DiffRelationshipComputer implements IDiffRelationshipComputer {
+
+ /** Merger registry used to retrieve the correct merger. */
+ protected Registry registry;
+
+ /** Merge criterion used to retrieve the correct merger. */
+ protected IMergeCriterion criterion;
+
+ /**
+ * Creates a new relationship computer.
+ *
+ * @param registry
+ * merger registry
+ */
+ public DiffRelationshipComputer(IMerger.Registry registry) {
+ this(registry, IMergeCriterion.NONE);
+ }
+
+ /**
+ * Creates a new relationship computer.
+ *
+ * @param registry
+ * merger registry
+ * @param criterion
+ * merge criterion used to get the merger from the registry, use {@link IMergeCriterion#NONE}
+ * if no special criterion should be set.
+ */
+ public DiffRelationshipComputer(IMerger.Registry registry, IMergeCriterion criterion) {
+ this.registry = registry;
+ this.criterion = criterion;
+ }
+
+ @Override
+ public Registry getMergerRegistry() {
+ return registry;
+ }
+
+ @Override
+ public void setMergerRegistry(Registry mergerRegistry) {
+ this.registry = mergerRegistry;
+ }
+
+ @Override
+ public IMergeCriterion getMergeCriterion() {
+ return criterion;
+ }
+
+ @Override
+ public void setMergeCriterion(IMergeCriterion mergeCriterion) {
+ this.criterion = mergeCriterion;
+ }
+
+ /**
+ * Returns the {@link #getMergerRegistry() merger registry} as {@link Registry2}, if possible. If the
+ * merger registry is not an instance of {@link Registry2}, null is returned.
+ *
+ * @return {@link Registry2} instance or null.
+ */
+ protected Registry2 getMergerRegistry2() {
+ if (registry instanceof Registry2) {
+ return (Registry2)registry;
+ }
+ return null;
+ }
+
+ @Override
+ public IMerger2 getMerger(Diff diff) {
+ if (getMergerRegistry2() == null) {
+ return null;
+ }
+
+ DelegatingMerger mergerDelegate = AbstractMerger.getMergerDelegate(diff, getMergerRegistry2(),
+ getMergeCriterion());
+ IMerger merger = mergerDelegate.getMerger();
+ if (!(merger instanceof IMerger2)) {
+ return null;
+ }
+
+ return (IMerger2)merger;
+ }
+
+ @Override
+ public boolean hasMerger(Diff diff) {
+ return getMerger(diff) != null;
+ }
+
+ @Override
+ public Set<Diff> getDirectMergeDependencies(Diff diff, boolean mergeRightToLeft) {
+ IMerger2 merger = getMerger(diff);
+ if (merger != null) {
+ return merger.getDirectMergeDependencies(diff, mergeRightToLeft);
+ }
+ return Sets.newHashSet();
+ }
+
+ @Override
+ public Set<Diff> getDirectResultingMerges(Diff diff, boolean mergeRightToLeft) {
+ IMerger2 merger = getMerger(diff);
+ if (merger != null) {
+ return merger.getDirectResultingMerges(diff, mergeRightToLeft);
+ }
+ return Sets.newHashSet();
+ }
+
+ @Override
+ public Set<Diff> getDirectResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ IMerger2 merger = getMerger(diff);
+ if (merger != null) {
+ return merger.getDirectResultingRejections(diff, mergeRightToLeft);
+ } else {
+ return Sets.newHashSet();
+ }
+ }
+
+ @Override
+ public Set<Diff> getAllResultingMerges(Diff diff, boolean rightToLeft) {
+ final Set<Diff> resultingMerges = new LinkedHashSet<Diff>();
+ resultingMerges.add(diff);
+
+ Set<Diff> relations = internalGetAllResultingMerges(diff, rightToLeft);
+ // We don't want to take in account pseudo conflicts since there is nothing to do with them
+ // and their dependencies may cause incorrect merge dependencies computation.
+ Set<Diff> difference = Sets.filter(Sets.difference(relations, resultingMerges),
+ not(hasConflict(PSEUDO)));
+ while (!difference.isEmpty()) {
+ final Set<Diff> newRelations = new LinkedHashSet<Diff>(difference);
+ resultingMerges.addAll(newRelations);
+ relations = new LinkedHashSet<Diff>();
+ for (Diff newRelation : newRelations) {
+ Set<Diff> internalResultingMerges = internalGetAllResultingMerges(newRelation, rightToLeft);
+ // We don't want to take in account pseudo conflicts since there is nothing to do with them
+ // and there dependencies may cause incorrect merge dependencies computation.
+ relations.addAll(Sets.filter(internalResultingMerges, not(hasConflict(PSEUDO))));
+ }
+ difference = Sets.difference(relations, resultingMerges);
+ }
+
+ // If a pseudo conflict is directly selected, we want to display other diffs of the pseudo conflict as
+ // resulting merge for the user
+ if (diff.getConflict() != null && diff.getConflict().getKind() == PSEUDO) {
+ resultingMerges.addAll(diff.getConflict().getDifferences());
+ }
+
+ return resultingMerges;
+ }
+
+ /**
+ * Returns the set of all differences <b>directly</b> related to the given one, either as dependencies or
+ * as implications.
+ *
+ * @param diff
+ * The difference for which we seek all directly related others.
+ * @param rightToLeft
+ * The direction in which we're considering a merge.
+ * @return The set of all differences <b>directly</b> related to the given one.
+ */
+ protected Set<Diff> internalGetAllResultingMerges(Diff diff, boolean rightToLeft) {
+ final Set<Diff> directParents = getDirectMergeDependencies(diff, rightToLeft);
+ final Set<Diff> directImplications = getDirectResultingMerges(diff, rightToLeft);
+ final SetView<Diff> directRelated = Sets.union(directParents, directImplications);
+ return directRelated;
+ }
+
+ @Override
+ public Set<Diff> getAllResultingRejections(Diff diff, boolean mergeRightToLeft) {
+ final Set<Diff> resultingRejections = new LinkedHashSet<Diff>();
+ final Set<Diff> allResultingMerges = getAllResultingMerges(diff, mergeRightToLeft);
+ resultingRejections.addAll(
+ Sets.filter(allResultingMerges, and(not(hasConflict(PSEUDO)), not(sameSideAs(diff)))));
+ // Only search rejections caused by diffs on the same side
+ for (Diff resulting : Sets.filter(allResultingMerges, sameSideAs(diff))) {
+ Set<Diff> rejections = getDirectResultingRejections(resulting, mergeRightToLeft);
+ // We don't want to take in account pseudo conflicts since there is nothing to do with them
+ // and their dependencies may cause incorrect merge dependencies computation.
+ Set<Diff> difference = Sets.filter(rejections, not(hasConflict(PSEUDO)));
+ while (!difference.isEmpty()) {
+ final Set<Diff> newRejections = new LinkedHashSet<Diff>(difference);
+ resultingRejections.addAll(newRejections);
+ rejections = new LinkedHashSet<Diff>();
+ for (Diff rejected : newRejections) {
+ Set<Diff> directMergeDependencies = getDirectMergeDependencies(rejected,
+ mergeRightToLeft);
+ // We don't want to take in account pseudo conflicts since there is nothing to do with
+ // them and their dependencies may cause incorrect merge dependencies computation.
+ // We also don't want to consider diffs on the same side for rejections
+ rejections.addAll(Sets.filter(directMergeDependencies,
+ and(not(hasConflict(PSEUDO)), not(sameSideAs(diff)))));
+ Set<Diff> directResultingMerges = getDirectResultingMerges(rejected, mergeRightToLeft);
+ rejections.addAll(Sets.filter(directResultingMerges,
+ and(not(hasConflict(PSEUDO)), not(sameSideAs(diff)))));
+ }
+ difference = Sets.difference(rejections, resultingRejections);
+ }
+ }
+ return resultingRejections;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IDiffRelationshipComputer.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IDiffRelationshipComputer.java
new file mode 100644
index 000000000..56ceaabe8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IDiffRelationshipComputer.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.merge;
+
+import java.util.Set;
+
+import org.eclipse.emf.compare.Diff;
+
+/**
+ * A computer to retrieve the dependent diffs, resulting merges and resulting rejections for a diff.
+ *
+ * @since 3.5
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ * @see IMerger2
+ */
+public interface IDiffRelationshipComputer {
+ /**
+ * Retrieves the set of directly required diffs needed in order to merge the given <code>diff</code>. This
+ * may includes the diff's requirements or any other diff that we need to merge before the given one.
+ *
+ * @param diff
+ * The difference for which we seek the direct merge dependencies.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return A non-null set of direct merge dependencies.
+ * @see IMerger2#getDirectMergeDependencies(Diff, boolean)
+ */
+ Set<Diff> getDirectMergeDependencies(Diff diff, boolean mergeRightToLeft);
+
+ /**
+ * Returns all differences that will be merged because of our merging the given <code>diff</code>. This
+ * may include the diff's implications, the diff's equivalences, the diff's refinements or any other diff
+ * that we need to merge together with the given diff.
+ *
+ * @param diff
+ * The difference for which we seek the direct merge dependencies.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return A non-null set of direct resulting merges.
+ * @see IMerger2#getDirectResultingMerges(Diff, boolean)
+ */
+ Set<Diff> getDirectResultingMerges(Diff diff, boolean mergeRightToLeft);
+
+ /**
+ * Returns the set of all differences that need to be rejected if <code>diff</code> is merged in the given
+ * direction.
+ *
+ * @param diff
+ * The difference for which we seek the direct resulting rejections.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return A non-null set of direct resulting rejections.
+ * @see #getAllResultingRejections(Diff, boolean)
+ * @see IMerger2#getDirectResultingRejections(Diff, boolean)
+ */
+ Set<Diff> getDirectResultingRejections(Diff diff, boolean mergeRightToLeft);
+
+ /**
+ * Retrieves the set of all diffs related to the given <code>diff</code> when merging in the given
+ * direction.
+ * <p>
+ * This is expected to return the set of all differences that will be need to merged along when a user
+ * wishes to merge <code>diff</code>, either because they are required by it or because they are implied
+ * by it one way or another.
+ * </p>
+ * <p>
+ * Note that <code>diff</code> will be included in the returned set.
+ * </p>
+ * <p>
+ * Also note that the resulting merges will contain the resulting rejections (diffs from the other side
+ * that will be rejected)
+ * </p>
+ *
+ * @param diff
+ * The difference for which we seek all related ones.
+ * @param rightToLeft
+ * The direction in which we're considering a merge.
+ * @return A non-null set of all diffs related to the given <code>diff</code> when merging in the given
+ * direction.
+ */
+ Set<Diff> getAllResultingMerges(Diff diff, boolean rightToLeft);
+
+ /**
+ * Retrieves the set of all diffs that will be rejected if the given <code>diff</code> is merged, either
+ * because of unresolveable conflicts or because of unreachable requirements.
+ *
+ * @param diff
+ * The difference for which we seek all opposite ones.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return A non-null set of all diffs that will be rejected if the given <code>diff</code> is merged in
+ * the given direction.
+ */
+ Set<Diff> getAllResultingRejections(Diff diff, boolean mergeRightToLeft);
+
+ /**
+ * Returns the merger registry used for calculating the diff relationships.
+ *
+ * @return The merger registry.
+ */
+ IMerger.Registry getMergerRegistry();
+
+ /**
+ * Sets the merger registry used for calculating the diff relationships.
+ *
+ * @param mergerRegistry
+ * The merger registry.
+ */
+ void setMergerRegistry(IMerger.Registry mergerRegistry);
+
+ /**
+ * Returns the merge criterion considered for calculating the diff relationships.
+ *
+ * @return The merge criterion.
+ */
+ IMergeCriterion getMergeCriterion();
+
+ /**
+ * Sets the merge criterion considered for calculating the diff relationships.
+ *
+ * @param mergeCriterion
+ * The merger criterion.
+ */
+ void setMergeCriterion(IMergeCriterion mergeCriterion);
+
+ /**
+ * Returns the best-fitting merger for the given diff according to the {@link #getMergerRegistry() merger
+ * registry} and the {@link #getMergeCriterion() merge criterion}.
+ *
+ * @param diff
+ * The difference for which we seek the merger.
+ * @return The best-fitting merger for the given diff or null if no merger fits.
+ */
+ IMerger2 getMerger(Diff diff);
+
+ /**
+ * Indicates whether a best-fitting merger for the given diff is available.
+ *
+ * @param diff
+ * The difference for which we seek the merger.
+ * @return Returns true if a best-fitting merger is available, false otherwise.
+ */
+ boolean hasMerger(Diff diff);
+}

Back to the top