diff options
22 files changed, 806 insertions, 14 deletions
diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/META-INF/MANIFEST.MF index 324be0697..f0aafa4cc 100644 --- a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/META-INF/MANIFEST.MF @@ -38,7 +38,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.emf.compare.rcp.ui.tests, org.eclipse.emf.compare.ide.ui.tests;bundle-version="4.0.0", org.eclipse.emf.compare.uml2.rcp.ui.tests;bundle-version="2.2.0", - org.eclipse.emf.compare.uml2.ide.tests + org.eclipse.emf.compare.uml2.ide.tests, + org.eclipse.emf.compare.ide.ui.tests.framework Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-Vendor: %providerName Import-Package: com.google.common.base;version="[15.0.0,22.0.0)", diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/MergeNonConflictingCascadingFilterTest.java b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/MergeNonConflictingCascadingFilterTest.java new file mode 100644 index 000000000..7b511fe99 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/MergeNonConflictingCascadingFilterTest.java @@ -0,0 +1,527 @@ +/******************************************************************************* + * 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.diagram.papyrus.tests.structuremergeviewer.actions; + +import static com.google.common.collect.Iterables.all; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.eclipse.emf.compare.DifferenceState.MERGED; +import static org.eclipse.emf.compare.DifferenceState.UNRESOLVED; +import static org.eclipse.emf.compare.merge.AbstractMerger.SUB_DIFF_AWARE_OPTION; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.containsConflictOfTypes; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Conflict; +import org.eclipse.emf.compare.ConflictKind; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceState; +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.MergeNonConflictingRunnable; +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.MergeMode; +import org.eclipse.emf.compare.merge.IMergeOptionAware; +import org.eclipse.emf.compare.merge.IMerger.Registry; +import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Model; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.PackageableElement; +import org.junit.runner.RunWith; + +/** + * <p> + * This class tests the expected behavior of accepting non-conflicting changes when the cascading differences + * filter is enabled. The cascading differences filter handles the setting of sub-diff awareness in mergers. + * </p> + * <p> + * In particular, we test that bug 487151 is fixed where conflicting diffs are merged when 'accepting + * non-conflicting changes'. The source of this bug lies in the sub-diff awareness of mergers that merge + * sub-diffs, their dependendies, their sub-diffs, etc. Therefore, this bug only occurs when sub-diff + * awareness ('cascading differences filter' to the user) is enabled. + * </p> + * We use the following structure to test the correct behavior: + * <ul> + * <li>Origin: Package 'Package1' containing class 'Class1'</li> + * <li>Left: Package 'Package1' (class 'Class1' removed)</li> + * <li>Right: Package 'Package1' containing class 'Class1', and class 'Class2' subclassing class 'Class1' + * (class 'Class2' and generalization added) + * </ul> + * For EMF Compare this means that we have the following relationships between the UML differences: + * <ul> + * <li>L1: Left DELETE Class 1 (conflicts with R4)</li> + * <li>R1: Right ADD Class 2 (subDiffs because also related to Class 2: R2 and R3)</li> + * <li>R2: Right ADD Generalization (refinedBy R3 and R4)</li> + * <li>R3: Right ADD generalization to Class2.generalization</li> + * <li>R4: Right CHANGE generalization.general to Class 1 (conflicts with L1)</li> + * </ul> + * <p> + * In the comparison, we detect a conflict between adding the generalization, setting the 'general' of the + * generalization and the deletion of class 'Class1'. When accepting all non-conflicting changes (left changes + * accepted, right changes merged into left for non-conflicts), we expect the left model to add nothing when + * sub-diffs are enabled and to add Class 2 (R1) when sub-diffs are not enabled. The generalization (R2-R4) + * should not be added in any case since in UML we consider the addition of the generalization and the setting + * of the 'general' as a whole (DirectedRelationshipChange) and the 'general' can not be set since 'Class2' + * has been removed (conflict). + * </p> + * <p> + * All non-conflicting diffs should be in state {@link DifferenceState#MERGED} and all conflicting diffs + * should be in state {@link DifferenceState#UNRESOLVED}. + * </p> + * + * @author Martin Fleck <mfleck@eclipsesource.com> + * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=487151 + */ +@SuppressWarnings({"restriction", "nls", "boxing" }) +@RunWith(RuntimeTestRunner.class) +public class MergeNonConflictingCascadingFilterTest { + /** Cached cascading options before the last time the filter was enabled or disabled. */ + private static final Map<IMergeOptionAware, Object> CACHED_OPTIONS = Maps.newHashMap(); + + private static Registry MERGER_REGISTRY = EMFCompareRCPPlugin.getDefault().getMergerRegistry(); + + /** Filter On setting **/ + private static boolean FILTER_ON = true; + + /** Filter Off setting **/ + private static boolean FILTER_OFF = false; + + /** + * <p> + * Tests that bug 487151 is fixed when the cascading differences filter is turned ON and graphical + * elements and their relationships are involved. + * </p> + */ + @Compare(left = "data/bug487151/classes/left/left.notation", right = "data/bug487151/classes/right/right.notation", ancestor = "data/bug487151/classes/origin/ancestor.notation") + public void testBug487151_Papyrus_On(final Comparison comparison) { + // lots of graphical diffs, details not important + Integer nrDiffs = null; + + // 1 REAL structural and 1 REAL graphical + int nrRealConflicts = 2; + + // graphical diffs are not conflicting + boolean hasNonConflictingDiffs = true; + + // conflicting structural differences: LEFT delete Class1, RIGHT change Generalization.general, RIGHT + // add DirectedRelationshipChange + graphical differences: ... + boolean hasConflictingDiffs = true; + + assertUMLDiffsAndStructure(comparison, FILTER_ON, nrDiffs, nrRealConflicts, hasNonConflictingDiffs, + hasConflictingDiffs); + } + + /** + * <p> + * Tests that bug 487151 is fixed when the cascading differences filter is turned OFF and graphical + * elements and their relationships are involved. + * </p> + */ + @Compare(left = "data/bug487151/classes/left/left.notation", right = "data/bug487151/classes/right/right.notation", ancestor = "data/bug487151/classes/origin/ancestor.notation") + public void testBug487151_Papyrus_Off(final Comparison comparison) { + // lots of graphical diffs, details not important + Integer nrDiffs = null; + + // 1 REAL structural and 1 REAL graphical + int nrRealConflicts = 2; + + // graphical diffs are not conflicting + boolean hasNonConflictingDiffs = true; + + // conflicting structural differences: LEFT delete Class1, RIGHT change Generalization.general, RIGHT + // add DirectedRelationshipChange + graphical differences: ... + boolean hasConflictingDiffs = true; + + assertUMLDiffsAndStructure(comparison, FILTER_OFF, nrDiffs, nrRealConflicts, hasNonConflictingDiffs, + hasConflictingDiffs); + } + + /** + * <p> + * Tests that bug 487151 is fixed when the cascading differences filter is turned ON and only UML elements + * and their relationships are involved. + * </p> + */ + @Compare(left = "data/bug487151/classes/left/left.uml", right = "data/bug487151/classes/right/right.uml", ancestor = "data/bug487151/classes/origin/ancestor.uml") + public void testBug487151_UML_On(final Comparison comparison) { + // 5 differences: LEFT delete Class1, RIGHT add Class2, RIGHT add generalization, RIGHT change + // Generalization.general, RIGHT add DirectedRelationshipChange (refining add/change for + // Generalization; from UML PostProcessor) + int nrDiffs = 5; + + // 1 REAL structural conflict + int nrRealConflicts = 1; + + // all diffs are in conflict through their relationships + boolean hasNonConflictingDiffs = false; + boolean hasConflictingDiffs = true; + + assertUMLDiffsAndStructure(comparison, FILTER_ON, nrDiffs, nrRealConflicts, hasNonConflictingDiffs, + hasConflictingDiffs); + } + + /** + * <p> + * Tests that bug 487151 is fixed when the cascading differences filter is turned OFF and only UML + * elements and their relationships are involved. + * </p> + */ + @Compare(left = "data/bug487151/classes/left/left.uml", right = "data/bug487151/classes/right/right.uml", ancestor = "data/bug487151/classes/origin/ancestor.uml") + public void testBug487151_UML_Off(final Comparison comparison) { + // 5 differences: LEFT delete Class1, RIGHT add Class2, RIGHT add generalization, RIGHT change + // Generalization.general, RIGHT add DirectedRelationshipChange (refining add/change for + // Generalization; from UML PostProcessor) + int nrDiffs = 5; + + // 1 REAL structural conflict + int nrRealConflicts = 1; + + // all diffs are in conflict through their relationships + boolean hasNonConflictingDiffs = true; + boolean hasConflictingDiffs = true; + + assertUMLDiffsAndStructure(comparison, FILTER_OFF, nrDiffs, nrRealConflicts, hasNonConflictingDiffs, + hasConflictingDiffs); + } + + /** + * <p> + * Tests that bug 487151 is fixed when the cascading differences filter is turned ON and and Ecore + * representation is used. Since we do not use refinement in Ecore and the Generalization is represented + * as a reference, Class 2 can be added independently of the filter setting. + * </p> + * <ul> + * <li>Origin: Package 'Package1' containing class 'Class1'</li> + * <li>Left: Package 'Package1' (class 'Class1' removed)</li> + * <li>Right: Package 'Package1' containing class 'Class1' and class 'Class2' with reference named + * 'Generalization' that has as eType 'Class1' (class 'Class2' and added generalization reference) + * </ul> + * <p> + * In the comparison, we detect a conflict between setting the eType of the 'Generalization' reference and + * the deletion of class 'Class1'. When accepting all non-conflicting changes (left changes accepted, + * right changes merged into left for non-conflicts), we expect the left model to have 'Class2' AND the + * 'Generalization' reference without an eType since 'Class1' has been deleted. All non-conflicting diffs + * should be in state {@link DifferenceState#MERGED} and all conflicting diffs should be in state + * {@link DifferenceState#UNRESOLVED}. + * </p> + */ + @Compare(left = "data/bug487151/ecore/left/left.ecore", right = "data/bug487151/ecore/right/right.ecore", ancestor = "data/bug487151/ecore/origin/ancestor.ecore") + public void testBug487151_Ecore_On(final Comparison comparison, final CompareTestSupport support) { + // 4 differences: LEFT delete Class1, RIGHT add Class2, RIGHT add generalization, RIGHT change + // Generalization.general + int nrDiffs = 4; + + // 1 conflict (REAL) + int nrRealConflicts = 1; + + // non-conflicting difference: RIGHT add Class2 + boolean hasNonConflictingDiffs = true; + + // conflicting differences: LEFT delete Class1, RIGHT change Generalization.eType, RIGHT add + // DirectedRelationshipChange + boolean hasConflictingDiffs = true; + + assertEcoreDiffsAndStructure(comparison, support, FILTER_ON, nrDiffs, nrRealConflicts, + hasNonConflictingDiffs, hasConflictingDiffs); + } + + /** + * <p> + * Tests that bug 487151 is fixed when the cascading differences filter is turned ON and and Ecore + * representation is used. Since we do not use refinement in Ecore and the Generalization is represented + * as a reference, Class 2 can be added independently of the filter setting. + * </p> + * <ul> + * <li>Origin: Package 'Package1' containing class 'Class1'</li> + * <li>Left: Package 'Package1' (class 'Class1' removed)</li> + * <li>Right: Package 'Package1' containing class 'Class1' and class 'Class2' with reference named + * 'Generalization' that has as eType 'Class1' (class 'Class2' and added generalization reference) + * </ul> + * <p> + * In the comparison, we detect a conflict between setting the eType of the 'Generalization' reference and + * the deletion of class 'Class1'. When accepting all non-conflicting changes (left changes accepted, + * right changes merged into left for non-conflicts), we expect the left model to have 'Class2' AND the + * 'Generalization' reference without an eType since 'Class1' has been deleted. All non-conflicting diffs + * should be in state {@link DifferenceState#MERGED} and all conflicting diffs should be in state + * {@link DifferenceState#UNRESOLVED}. + * </p> + */ + @Compare(left = "data/bug487151/ecore/left/left.ecore", right = "data/bug487151/ecore/right/right.ecore", ancestor = "data/bug487151/ecore/origin/ancestor.ecore") + public void testBug487151_Ecore_Off(final Comparison comparison, final CompareTestSupport support) { + // 4 differences: LEFT delete Class1, RIGHT add Class2, RIGHT add generalization, RIGHT change + // Generalization.general + int nrDiffs = 4; + + // 1 conflict (REAL) + int nrRealConflicts = 1; + + // non-conflicting difference: RIGHT add Class2 + boolean hasNonConflictingDiffs = true; + + // conflicting differences: LEFT delete Class1, RIGHT change Generalization.eType, RIGHT add + // DirectedRelationshipChange + boolean hasConflictingDiffs = true; + + assertEcoreDiffsAndStructure(comparison, support, FILTER_OFF, nrDiffs, nrRealConflicts, + hasNonConflictingDiffs, hasConflictingDiffs); + } + + /** + * Asserts the expected differences and structure for Ecore models. Specifically, that independently of + * the filter setting, the class 2 and its generalization is added, but the type of the generalization is + * not set. + * + * @param comparison + * comparison + * @param support + * test support for the comparison + * @param filter + * sub-diff filter setting + * @param nrDiffs + * expected number of differences + * @param nrRealConflicts + * expected number of real conflicts + * @param hasNonConflictingDiffs + * whether non-conflicting diffs are expected + * @param hasConflictingDiffs + * whether conflicting diffs are expected + */ + protected void assertEcoreDiffsAndStructure(Comparison comparison, CompareTestSupport support, + boolean filter, int nrDiffs, int nrRealConflicts, boolean hasNonConflictingDiffs, + boolean hasConflictingDiffs) { + final List<Diff> differences = comparison.getDifferences(); + final List<Conflict> conflicts = comparison.getConflicts(); + + // 4 differences: LEFT delete Class1, RIGHT add Class2, RIGHT add generalization, RIGHT change + // Generalization.general + assertEquals(nrDiffs, differences.size()); + + // real conflicts + Iterable<Conflict> realConflicts = filter(conflicts, containsConflictOfTypes(ConflictKind.REAL)); + assertEquals(nrRealConflicts, size(realConflicts)); + + // before accepting any changes, all differences are unresolved + assertTrue(all(differences, hasState(UNRESOLVED))); + + // accept non-conflicting changes and collect differences + Iterable<Diff> nonConflictingDifferences = acceptNonConflictingChanges(comparison, filter); + assertEquals(hasNonConflictingDiffs, !isEmpty(nonConflictingDifferences)); + + // conflicting differences: LEFT delete Class1, RIGHT change Generalization.eType, RIGHT add + // DirectedRelationshipChange + final List<Diff> conflictingDifferences = getConflictingDifferences( + Lists.newArrayList(nonConflictingDifferences), conflicts); + assertEquals(hasConflictingDiffs, !isEmpty(conflictingDifferences)); + + // all accepted differences have been merged + assertTrue(all(nonConflictingDifferences, hasState(MERGED))); + + // any differences part of real conflicts are still unresolved + assertTrue(all(conflictingDifferences, hasState(UNRESOLVED))); + + // assert new structure (right changes merged into left for non-conflicts) + EObject root = support.getLeftResource().getContents().get(0); + assertNotNull(root); + assertTrue(root instanceof EPackage); + EPackage package1 = (EPackage)root; + assertNotNull(package1); + EClassifier class1 = package1.getEClassifier("Class1"); + assertNull(class1); // still null due to conflict + EClassifier class2 = package1.getEClassifier("Class2"); + + // regardless of filter, class 2 and generalization is added + assertNotNull(class2); // newly added + EClass class2class = (EClass)class2; + EStructuralFeature class2generalization = class2class.getEStructuralFeature("Generalization"); + assertNotNull(class2generalization); // reference generalization has been added + assertNull(class2generalization.getEType()); // no type set due to conflict + } + + /** + * Asserts the expected differences and structure for UML models. Specifically, whether Class 2 + * conflicting with sub-diff filter enabled is added. + * + * @param comparison + * comparison + * @param filter + * sub-diff filter setting + * @param nrDiffs + * expected number of differences + * @param nrRealConflicts + * expected number of real conflicts + * @param hasNonConflictingDiffs + * whether non-conflicting diffs are expected + * @param hasConflictingDiffs + * whether conflicting diffs are expected + */ + protected void assertUMLDiffsAndStructure(Comparison comparison, boolean filter, Integer nrDiffs, + int nrRealConflicts, boolean hasNonConflictingDiffs, boolean hasConflictingDiffs) { + final List<Diff> differences = comparison.getDifferences(); + final List<Conflict> conflicts = comparison.getConflicts(); + + if (nrDiffs != null) { + assertEquals(nrDiffs.intValue(), differences.size()); + } + + Iterable<Conflict> realConflicts = filter(conflicts, containsConflictOfTypes(ConflictKind.REAL)); + assertEquals(nrRealConflicts, size(realConflicts)); + + // before accepting any changes, all differences are unresolved + assertTrue(all(differences, hasState(UNRESOLVED))); + + // accept non-conflicting changes and collect differences + Iterable<Diff> nonConflictingDifferences = acceptNonConflictingChanges(comparison, filter); + assertEquals(hasNonConflictingDiffs, !isEmpty(nonConflictingDifferences)); + + // get conflicting diffs + final List<Diff> conflictingDifferences = getConflictingDifferences( + Lists.newArrayList(nonConflictingDifferences), Lists.newArrayList(realConflicts)); + assertEquals(hasConflictingDiffs, !conflictingDifferences.isEmpty()); + + // all accepted differences have been merged + assertTrue(all(nonConflictingDifferences, hasState(MERGED))); + + // any differences part of real conflicts are still unresolved + assertTrue(all(conflictingDifferences, hasState(UNRESOLVED))); + + // assert new structure (right changes merged into left for non-conflicts) + EObject root = getLeftUMLRoot(comparison); + assertNotNull(root); + assertTrue(root instanceof Model); + Model model = (Model)root; + Package package1 = (Package)model.getPackagedElement("Package1"); + assertNotNull(package1); + PackageableElement class1 = package1.getPackagedElement("Class1"); + assertNull(class1); // still null due to conflict + PackageableElement class2 = package1.getPackagedElement("Class2"); + if (filter == FILTER_OFF) { + assertNotNull(class2); + Class class2class = (Class)class2; + assertTrue(class2class.getGeneralizations().isEmpty()); // no generalization added due to conflict + } else { + assertNull(class2); // class not added, because sub-diffs are in conflict + } + } + + /** + * Returns the root element of the left UML resource or null if no such element can be found. + * + * @param comparison + * comparison + * @return left root element + */ + protected static EObject getLeftUMLRoot(Comparison comparison) { + for (MatchResource resource : comparison.getMatchedResources()) { + if (resource.getLeft().getURI().lastSegment().endsWith("uml")) { + return resource.getLeft().getContents().get(0); + } + } + return null; + } + + /** + * Accepts all non-conflicting changes. The left changes will be accepted and the right changes will be + * merged into the left-hand side. + * + * @param comparison + * comparison with differences + * @param leftToRight + * direction of merge + * @return affected differences + */ + protected static Iterable<Diff> acceptNonConflictingChanges(Comparison comparison, + boolean cascadingFilter) { + boolean leftToRight = false; + boolean isLeftEditable = true; + boolean isRightEditable = false; + setCascadingFilter(cascadingFilter); + MergeNonConflictingRunnable mergeNonConflicting = new MergeNonConflictingRunnable(isLeftEditable, + isRightEditable, MergeMode.ACCEPT, null); + Iterable<Diff> mergedDiffs = mergeNonConflicting.merge(comparison, leftToRight, MERGER_REGISTRY); + restoreCascadingFilter(); + return mergedDiffs; + } + + /** + * Returns a list of all differences that part of a conflict and ensures that there is no overlap between + * conflicting and non-conflicting diffs. + * + * @param realConflicts + * conflicts + * @return conflicting differences + */ + protected static List<Diff> getConflictingDifferences(List<Diff> nonConflictingDiffs, + List<Conflict> realConflicts) { + ArrayList<Diff> conflictingDiffs = Lists.newArrayList(); + for (Conflict conflict : realConflicts) { + EList<Diff> conflctDiffs = conflict.getDifferences(); + conflictingDiffs.addAll(conflctDiffs); + } + + // assert no overlap between non-conflicting and conflicting + assertFalse(nonConflictingDiffs.removeAll(conflictingDiffs)); + assertFalse(conflictingDiffs.removeAll(nonConflictingDiffs)); + + return conflictingDiffs; + } + + /** + * Sets the cascading filter option (subdiff-awareness) of all mergers to the given state. Any changes + * done by this method can be restored by calling {@link #restoreCascadingFilter()}. + * + * @param enabled + * filter state + */ + protected static void setCascadingFilter(boolean enabled) { + for (IMergeOptionAware merger : Iterables.filter(MERGER_REGISTRY.getMergers(null), + IMergeOptionAware.class)) { + Map<Object, Object> mergeOptions = merger.getMergeOptions(); + Object previousValue = mergeOptions.get(SUB_DIFF_AWARE_OPTION); + CACHED_OPTIONS.put(merger, previousValue); + mergeOptions.put(SUB_DIFF_AWARE_OPTION, Boolean.valueOf(enabled)); + } + } + + /** + * Restores the cascading filter options changed by the last call to {@link #enableCascadingFilter()}, + * {@link #disableCascadingFilter()}, or {@link #setCascadingFilter(boolean)}. + */ + protected static void restoreCascadingFilter() { + // restore previous values + for (Entry<IMergeOptionAware, Object> entry : CACHED_OPTIONS.entrySet()) { + IMergeOptionAware merger = entry.getKey(); + merger.getMergeOptions().put(SUB_DIFF_AWARE_OPTION, entry.getValue()); + } + } +} diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.di b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.di new file mode 100644 index 000000000..bf9abab34 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.notation b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.notation new file mode 100644 index 000000000..17aac1777 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.notation @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_e5YrAC8QEeacdOKGfrvgBQ" type="PapyrusUMLClassDiagram" name="ClassDiagram" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_h6JtUC8QEeacdOKGfrvgBQ" type="2007"> + <children xmi:type="notation:DecorationNode" xmi:id="_h6MJkC8QEeacdOKGfrvgBQ" type="5026"> + <element xmi:type="uml:Package" href="left.uml#_h585AC8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_h6MJkS8QEeacdOKGfrvgBQ" type="7016"> + <styles xmi:type="notation:TitleStyle" xmi:id="_h6MwoC8QEeacdOKGfrvgBQ"/> + <element xmi:type="uml:Package" href="left.uml#_h585AC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_h6MwoS8QEeacdOKGfrvgBQ"/> + </children> + <element xmi:type="uml:Package" href="left.uml#_h585AC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_h6JtUS8QEeacdOKGfrvgBQ" x="74" y="37" width="381" height="426"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_e5YrAS8QEeacdOKGfrvgBQ" name="diagram_compatibility_version" stringValue="1.1.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_e5YrAi8QEeacdOKGfrvgBQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_e5YrAy8QEeacdOKGfrvgBQ"> + <owner xmi:type="uml:Model" href="left.uml#_X6atwC8QEeacdOKGfrvgBQ"/> + </styles> + <element xmi:type="uml:Model" href="left.uml#_X6atwC8QEeacdOKGfrvgBQ"/> +</notation:Diagram> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.uml b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.uml new file mode 100644 index 000000000..dd04d3c22 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/left/left.uml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_X6atwC8QEeacdOKGfrvgBQ" name="RootElement"> + <packagedElement xmi:type="uml:Package" xmi:id="_h585AC8QEeacdOKGfrvgBQ" name="Package1"/> +</uml:Model> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.di b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.di new file mode 100644 index 000000000..bf9abab34 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.notation b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.notation new file mode 100644 index 000000000..f03a8dffc --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.notation @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_e5YrAC8QEeacdOKGfrvgBQ" type="PapyrusUMLClassDiagram" name="ClassDiagram" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_h6JtUC8QEeacdOKGfrvgBQ" type="2007"> + <children xmi:type="notation:DecorationNode" xmi:id="_h6MJkC8QEeacdOKGfrvgBQ" type="5026"/> + <children xmi:type="notation:BasicCompartment" xmi:id="_h6MJkS8QEeacdOKGfrvgBQ" type="7016"> + <children xmi:type="notation:Shape" xmi:id="_m-JLoC8QEeacdOKGfrvgBQ" type="3010"> + <children xmi:type="notation:DecorationNode" xmi:id="_m-JysC8QEeacdOKGfrvgBQ" type="5014"/> + <children xmi:type="notation:DecorationNode" xmi:id="_m-JysS8QEeacdOKGfrvgBQ" type="8518"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_m-Jysi8QEeacdOKGfrvgBQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_m-LA0C8QEeacdOKGfrvgBQ" type="7011"> + <styles xmi:type="notation:TitleStyle" xmi:id="_m-LA0S8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_m-LA0i8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_m-LA0y8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-LA1C8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_m-LA1S8QEeacdOKGfrvgBQ" type="7012"> + <styles xmi:type="notation:TitleStyle" xmi:id="_m-LA1i8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_m-LA1y8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_m-LA2C8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-LA2S8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_m-LA2i8QEeacdOKGfrvgBQ" type="7013"> + <styles xmi:type="notation:TitleStyle" xmi:id="_m-LA2y8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_m-LA3C8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_m-LA3S8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-LA3i8QEeacdOKGfrvgBQ"/> + </children> + <element xmi:type="uml:Class" href="ancestor.uml#_m-BP0C8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-JLoS8QEeacdOKGfrvgBQ" x="135" y="26"/> + </children> + <styles xmi:type="notation:TitleStyle" xmi:id="_h6MwoC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_h6MwoS8QEeacdOKGfrvgBQ"/> + </children> + <element xmi:type="uml:Package" href="ancestor.uml#_h585AC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_h6JtUS8QEeacdOKGfrvgBQ" x="74" y="37" width="381" height="426"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_e5YrAS8QEeacdOKGfrvgBQ" name="diagram_compatibility_version" stringValue="1.1.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_e5YrAi8QEeacdOKGfrvgBQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_e5YrAy8QEeacdOKGfrvgBQ"> + <owner xmi:type="uml:Model" href="ancestor.uml#_X6atwC8QEeacdOKGfrvgBQ"/> + </styles> + <element xmi:type="uml:Model" href="ancestor.uml#_X6atwC8QEeacdOKGfrvgBQ"/> +</notation:Diagram> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.uml b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.uml new file mode 100644 index 000000000..6829615c1 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/origin/ancestor.uml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_X6atwC8QEeacdOKGfrvgBQ" name="RootElement"> + <packagedElement xmi:type="uml:Package" xmi:id="_h585AC8QEeacdOKGfrvgBQ" name="Package1"> + <packagedElement xmi:type="uml:Class" xmi:id="_m-BP0C8QEeacdOKGfrvgBQ" name="Class1"/> + </packagedElement> +</uml:Model> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.di b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.di new file mode 100644 index 000000000..bf9abab34 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.notation b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.notation new file mode 100644 index 000000000..d58f1ca5a --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.notation @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_e5YrAC8QEeacdOKGfrvgBQ" type="PapyrusUMLClassDiagram" name="ClassDiagram" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_h6JtUC8QEeacdOKGfrvgBQ" type="2007"> + <children xmi:type="notation:DecorationNode" xmi:id="_h6MJkC8QEeacdOKGfrvgBQ" type="5026"> + <element xmi:type="uml:Package" href="right.uml#_h585AC8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_h6MJkS8QEeacdOKGfrvgBQ" type="7016"> + <children xmi:type="notation:Shape" xmi:id="_m-JLoC8QEeacdOKGfrvgBQ" type="3010"> + <children xmi:type="notation:DecorationNode" xmi:id="_m-JysC8QEeacdOKGfrvgBQ" type="5014"> + <element xmi:type="uml:Class" href="right.uml#_m-BP0C8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_m-JysS8QEeacdOKGfrvgBQ" type="8518"> + <element xmi:type="uml:Class" href="right.uml#_m-BP0C8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Location" xmi:id="_m-Jysi8QEeacdOKGfrvgBQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_m-LA0C8QEeacdOKGfrvgBQ" type="7011"> + <styles xmi:type="notation:TitleStyle" xmi:id="_m-LA0S8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_m-LA0i8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_m-LA0y8QEeacdOKGfrvgBQ"/> + <element xmi:type="uml:Class" href="right.uml#_m-BP0C8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-LA1C8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_m-LA1S8QEeacdOKGfrvgBQ" type="7012"> + <styles xmi:type="notation:TitleStyle" xmi:id="_m-LA1i8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_m-LA1y8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_m-LA2C8QEeacdOKGfrvgBQ"/> + <element xmi:type="uml:Class" href="right.uml#_m-BP0C8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-LA2S8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_m-LA2i8QEeacdOKGfrvgBQ" type="7013"> + <styles xmi:type="notation:TitleStyle" xmi:id="_m-LA2y8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_m-LA3C8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_m-LA3S8QEeacdOKGfrvgBQ"/> + <element xmi:type="uml:Class" href="right.uml#_m-BP0C8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-LA3i8QEeacdOKGfrvgBQ"/> + </children> + <element xmi:type="uml:Class" href="right.uml#_m-BP0C8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_m-JLoS8QEeacdOKGfrvgBQ" x="135" y="26"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_26D1wC8QEeacdOKGfrvgBQ" type="3010"> + <children xmi:type="notation:DecorationNode" xmi:id="_26Fq8C8QEeacdOKGfrvgBQ" type="5014"/> + <children xmi:type="notation:DecorationNode" xmi:id="_26Fq8S8QEeacdOKGfrvgBQ" type="8518"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_26Fq8i8QEeacdOKGfrvgBQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_26Fq8y8QEeacdOKGfrvgBQ" type="7011"> + <styles xmi:type="notation:TitleStyle" xmi:id="_26Fq9C8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_26Fq9S8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_26Fq9i8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_26Fq9y8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_26Fq-C8QEeacdOKGfrvgBQ" type="7012"> + <styles xmi:type="notation:TitleStyle" xmi:id="_26Fq-S8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_26Fq-i8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_26Fq-y8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_26Fq_C8QEeacdOKGfrvgBQ"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_26Fq_S8QEeacdOKGfrvgBQ" type="7013"> + <styles xmi:type="notation:TitleStyle" xmi:id="_26Fq_i8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:SortingStyle" xmi:id="_26Fq_y8QEeacdOKGfrvgBQ"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_26FrAC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_26FrAS8QEeacdOKGfrvgBQ"/> + </children> + <element xmi:type="uml:Class" href="right.uml#_259vIC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_26D1wS8QEeacdOKGfrvgBQ" x="135" y="247"/> + </children> + <styles xmi:type="notation:TitleStyle" xmi:id="_h6MwoC8QEeacdOKGfrvgBQ"/> + <element xmi:type="uml:Package" href="right.uml#_h585AC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_h6MwoS8QEeacdOKGfrvgBQ"/> + </children> + <element xmi:type="uml:Package" href="right.uml#_h585AC8QEeacdOKGfrvgBQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_h6JtUS8QEeacdOKGfrvgBQ" x="74" y="37" width="381" height="426"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_e5YrAS8QEeacdOKGfrvgBQ" name="diagram_compatibility_version" stringValue="1.1.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_e5YrAi8QEeacdOKGfrvgBQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_e5YrAy8QEeacdOKGfrvgBQ"> + <owner xmi:type="uml:Model" href="right.uml#_X6atwC8QEeacdOKGfrvgBQ"/> + </styles> + <element xmi:type="uml:Model" href="right.uml#_X6atwC8QEeacdOKGfrvgBQ"/> + <edges xmi:type="notation:Connector" xmi:id="_8W-xcC8QEeacdOKGfrvgBQ" type="4002" source="_26D1wC8QEeacdOKGfrvgBQ" target="_m-JLoC8QEeacdOKGfrvgBQ"> + <children xmi:type="notation:DecorationNode" xmi:id="_8W_YgC8QEeacdOKGfrvgBQ" type="6007"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_8W_YgS8QEeacdOKGfrvgBQ" y="40"/> + </children> + <styles xmi:type="notation:FontStyle" xmi:id="_8W-xcS8QEeacdOKGfrvgBQ"/> + <element xmi:type="uml:Generalization" href="right.uml#_8W21oC8QEeacdOKGfrvgBQ"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_8W-xci8QEeacdOKGfrvgBQ" points="[-1, -7, 1, 134]$[-4, -128, -2, 13]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_8XoRsC8QEeacdOKGfrvgBQ" id="(0.46,0.0)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_8XoRsS8QEeacdOKGfrvgBQ" id="(0.45,1.0)"/> + </edges> +</notation:Diagram> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.uml b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.uml new file mode 100644 index 000000000..51e98e25f --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/classes/right/right.uml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_X6atwC8QEeacdOKGfrvgBQ" name="RootElement"> + <packagedElement xmi:type="uml:Package" xmi:id="_h585AC8QEeacdOKGfrvgBQ" name="Package1"> + <packagedElement xmi:type="uml:Class" xmi:id="_m-BP0C8QEeacdOKGfrvgBQ" name="Class1"/> + <packagedElement xmi:type="uml:Class" xmi:id="_259vIC8QEeacdOKGfrvgBQ" name="Class2"> + <generalization xmi:type="uml:Generalization" xmi:id="_8W21oC8QEeacdOKGfrvgBQ" general="_m-BP0C8QEeacdOKGfrvgBQ"/> + </packagedElement> + </packagedElement> +</uml:Model> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/left/left.ecore b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/left/left.ecore new file mode 100644 index 000000000..0d46cfee6 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/left/left.ecore @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" + name="Package1"/> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/origin/ancestor.ecore b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/origin/ancestor.ecore new file mode 100644 index 000000000..dafdd97bd --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/origin/ancestor.ecore @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Package1"> + <eClassifiers xsi:type="ecore:EClass" name="Class1"/> +</ecore:EPackage> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/right/right.ecore b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/right/right.ecore new file mode 100644 index 000000000..77fea6515 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/structuremergeviewer/actions/data/bug487151/ecore/right/right.ecore @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage + xmi:version="2.0" + xmlns:xmi="http://www.omg.org/XMI" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" + name="Package1" + nsURI="" + nsPrefix=""> + <eClassifiers + xsi:type="ecore:EClass" + name="Class1"/> + <eClassifiers + xsi:type="ecore:EClass" + name="Class2"> + <eStructuralFeatures + xsi:type="ecore:EAttribute" + name="Generalization" + eType="#//Class1"/> + </eClassifiers> +</ecore:EPackage> diff --git a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/suite/AllTests.java index e01bb7284..2d7bca99c 100644 --- a/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/suite/AllTests.java +++ b/plugins/org.eclipse.emf.compare.diagram.papyrus.tests/src/org/eclipse/emf/compare/diagram/papyrus/tests/suite/AllTests.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 * Stefan Dirix - add ModelExtensionUtil, SaveParameterHook and URIAttachment tests * Philip Langer - add IngoreDiFileModelElementsTest + * Martin Fleck - add MergeNonConflictingCascadingDifferencesFilterTest *******************************************************************************/ package org.eclipse.emf.compare.diagram.papyrus.tests.suite; @@ -24,6 +25,7 @@ import org.eclipse.emf.compare.diagram.papyrus.tests.merge.NodeMergeTest; import org.eclipse.emf.compare.diagram.papyrus.tests.modelextension.ModelExtensionUtilTest; import org.eclipse.emf.compare.diagram.papyrus.tests.saveparameter.SaveParameterHookIntegrationTest; import org.eclipse.emf.compare.diagram.papyrus.tests.saveparameter.SaveParameterHookTest; +import org.eclipse.emf.compare.diagram.papyrus.tests.structuremergeviewer.actions.MergeNonConflictingCascadingFilterTest; import org.eclipse.emf.compare.diagram.papyrus.tests.uriattachment.URIAttachmentTest; import org.eclipse.emf.compare.tests.suite.CompareTestSuite; import org.eclipse.emf.ecore.EPackage; @@ -53,7 +55,8 @@ import junit.textui.TestRunner; @SuiteClasses({AssocMergeTest.class, EdgeMergeTest.class, NodeMergeTest.class, ModelExtensionUtilTest.class, SaveParameterHookTest.class, SaveParameterHookIntegrationTest.class, URIAttachmentTest.class, DiagramTooltipProviderTest.class, PapyrusConflictsGroupProviderTests.class, - IgnoreDiFilePostProcessorTest.class, PapyrusContextUtilTest.class }) + IgnoreDiFilePostProcessorTest.class, PapyrusContextUtilTest.class, + MergeNonConflictingCascadingFilterTest.class }) public class AllTests { /** diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/ConflictDetectionTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/ConflictDetectionTest.java index c88fb7951..258233138 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/ConflictDetectionTest.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/ConflictDetectionTest.java @@ -1931,6 +1931,22 @@ public class ConflictDetectionTest { } @Test + public void testE3UseCase() throws IOException { + final Resource left = input.getE3Left(); + final Resource origin = input.getE3Origin(); + final Resource right = input.getE3Right(); + + final IComparisonScope scope = new DefaultComparisonScope(left, right, origin); + final Comparison comparison = EMFCompare.builder().build().compare(scope); + + final List<Diff> differences = comparison.getDifferences(); + final List<Conflict> conflicts = comparison.getConflicts(); + + assertEquals(3, differences.size()); + assertEquals(1, conflicts.size()); + } + + @Test public void testFUseCase() throws IOException { final Resource left = input.getFLeft(); final Resource origin = input.getFOrigin(); diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/ConflictInputData.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/ConflictInputData.java index 4438a5369..396b70b30 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/ConflictInputData.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/ConflictInputData.java @@ -544,6 +544,18 @@ public class ConflictInputData extends AbstractInputData { return loadFromClassLoader("e2/conflict_e2_right.nodes"); } + public Resource getE3Left() throws IOException { + return loadFromClassLoader("e3/conflict_e3_left.nodes"); + } + + public Resource getE3Origin() throws IOException { + return loadFromClassLoader("e3/conflict_e3_origin.nodes"); + } + + public Resource getE3Right() throws IOException { + return loadFromClassLoader("e3/conflict_e3_right.nodes"); + } + public Resource getFLeft() throws IOException { return loadFromClassLoader("f/conflict_f_left.nodes"); } diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_left.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_left.nodes new file mode 100644 index 000000000..818e238da --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_left.nodes @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes"
+ xmi:id="_SSvAAJQ_EeGUu8zWDEISZA"
+ name="root"/>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_origin.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_origin.nodes new file mode 100644 index 000000000..f31a847a7 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_origin.nodes @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes"
+ xmi:id="_SSvAAJQ_EeGUu8zWDEISZA"
+ name="root">
+ <containmentRef1
+ xmi:id="_iQJe8JQ_EeGUu8zWDEISZA"
+ name="origin"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_right.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_right.nodes new file mode 100644 index 000000000..e2802cdb4 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/e3/conflict_e3_right.nodes @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" xmi:id="_SSvAAJQ_EeGUu8zWDEISZA" name="root">
+ <containmentRef1 xmi:id="_iQJe8JQ_EeGUu8zWDEISZA" name="origin"/>
+ <containmentRef1 xsi:type="nodes:NodeSingleValueReference" xmi:id="_kT6GcJQ_EeGUu8zWDEISZA" name="conflictHolder" singleValuedReference="_iQJe8JQ_EeGUu8zWDEISZA"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/useCases b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/useCases index 037dabf81..08c00b00b 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/useCases +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/conflict/data/useCases @@ -36,6 +36,7 @@ These only apply to reference changes e - Adding reference towards deleted Notifier.
e1 - Within single-valued reference.
e2 - Within multi-valued reference.
+ e3 - Add a single-valued reference on the right side to a node that has been deleted on the left side.
f - Changing containment feature of Notifier to two distinct features in left and right.
g - Changing container of Notifier to two distinct Notifiers in left and right.
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 c1469d570..3d8590238 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 @@ -17,12 +17,10 @@ import static org.eclipse.emf.compare.merge.IMergeCriterion.NONE; import com.google.common.base.Predicate; import com.google.common.collect.Sets; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import org.eclipse.emf.compare.Conflict; @@ -144,7 +142,7 @@ public class ComputeDiffsToMerge { * The diff to merge */ protected void addDiff(Diff diff) { - addDiffs(Collections.singleton(diff)); + addDiffs(Collections.singleton(diff), Sets.<Diff> newLinkedHashSet()); } /** @@ -153,16 +151,18 @@ public class ComputeDiffsToMerge { * * @param diffs * The diffs to merge at the current step of the computation + * @param diffPath + * The path that lead to a diff */ - protected void addDiffs(Collection<Diff> diffs) { + protected void addDiffs(Collection<Diff> diffs, Set<Diff> diffPath) { if (diffs.isEmpty()) { return; } Set<Diff> consequences = new LinkedHashSet<Diff>(); for (Diff diff : diffs) { - addDiff(diff, consequences); + addDiff(diff, consequences, diffPath); } - addDiffs(Sets.difference(consequences, result)); + addDiffs(Sets.difference(consequences, result), diffPath); } /** @@ -173,21 +173,22 @@ public class ComputeDiffsToMerge { * The diff to add * @param consequences * The set of diffs that must be merged at the next step. + * @param diffPath + * The path that lead to the diff to add */ - protected void addDiff(Diff diff, Set<Diff> consequences) { + protected void addDiff(Diff diff, Set<Diff> consequences, Set<Diff> diffPath) { if (!result.contains(diff) && computing.add(diff)) { + diffPath.add(diff); Conflict conflict = diff.getConflict(); if (conflictChecker != null && conflict != null && !conflictChecker.apply(conflict) && diff.getConflict().getKind() == REAL) { - List<Diff> diffsThatLedToConflict = new ArrayList<Diff>(result); - diffsThatLedToConflict.add(diff); - throw new MergeBlockedByConflictException(diffsThatLedToConflict); + throw new MergeBlockedByConflictException(diffPath); } if (relationshipComputer.hasMerger(diff)) { Set<Diff> dependencies = relationshipComputer.getDirectMergeDependencies(diff, rightToLeft); for (Diff required : dependencies) { - addDiff(required, consequences); + addDiff(required, consequences, Sets.newLinkedHashSet(diffPath)); } result.add(diff); |