Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2017-09-11 07:43:59 -0400
committerlgoubet2019-07-17 11:03:15 -0400
commit22c21612be43f38771b64e81a328ec215d470864 (patch)
treea3dbbc478b4252c99af017535a17bedd5617d061
parent1998e64ba331e977271a01a57e1e12dbb5a99148 (diff)
downloadorg.eclipse.emf.compare-master.tar.gz
org.eclipse.emf.compare-master.tar.xz
org.eclipse.emf.compare-master.zip
[522080] [UML] Add-add conflicts in stereotype application not detectedHEADmaster
Two changes in the UML post-processor to handle apply-apply and unapply-unapply conflicts for stereotype applications on the same element in both sides of the comparison: * re-match left- and right-side additions/removals of stereotype applications to match the same stereotype applied to the same element even though the XMI IDs are different * generate the attribute diffs in added stereotype applications that the default diff engine refuses to do, so that we may find conflicts in differing attribute values in the conflict phase (references are handled by the core) Bug: 522080 Change-Id: I4daac02414abc3f275ac9ff19d6a460b43a0fe84 Signed-off-by: Christian W. Damus <give.a.damus@gmail.com>
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/StereotypeApplicationConflictTests.java185
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/StereotypeApplicationConflictInputData.java93
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/left.uml13
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/origin.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/right.uml13
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/left.uml13
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/origin.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/right.uml13
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/left.uml13
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/origin.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/right.uml13
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/left.uml15
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/origin.uml12
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/right.uml15
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/left.uml15
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/origin.uml12
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/right.uml15
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/left.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/origin.uml16
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/right.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java7
-rw-r--r--plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/StereotypedElementChangePostProcessor.java224
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/conflict/AbstractConflictSearch.java13
23 files changed, 744 insertions, 6 deletions
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/StereotypeApplicationConflictTests.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/StereotypeApplicationConflictTests.java
new file mode 100644
index 000000000..048772d9f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/StereotypeApplicationConflictTests.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ * Christian W. Damus - bug 522080
+ *******************************************************************************/
+package org.eclipse.emf.compare.uml2.tests.stereotypes;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.eclipse.emf.common.EMFPlugin;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ConflictKind;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.uml2.profile.test.uml2comparetestprofile.UML2CompareTestProfilePackage;
+import org.eclipse.emf.compare.uml2.tests.AbstractUMLInputData;
+import org.eclipse.emf.compare.uml2.tests.stereotypes.data.conflict.StereotypeApplicationConflictInputData;
+import org.eclipse.emf.compare.utils.EMFComparePredicates;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.uml2.uml.UMLPlugin;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests add-add scenarios for stereotype applications (same stereotype applied to same element on both
+ * sides).
+ */
+@SuppressWarnings("nls")
+public class StereotypeApplicationConflictTests extends AbstractStereotypedElementChangeTests {
+
+ private StereotypeApplicationConflictInputData input;
+
+ /**
+ * Initializes me.
+ */
+ public StereotypeApplicationConflictTests() {
+ super();
+ }
+
+ /**
+ * Tests add-add conflict for a stereotype that defines no attributes.
+ */
+ @Test
+ public void testApplyApplyPseudoConflictStereotypeNoAttributes() throws IOException {
+ final Comparison comparison = compare(input.getA1Left(), input.getA1Right(), input.getA1Base());
+ EList<Diff> differences = comparison.getDifferences();
+
+ assertThat(differences, hasItem(hasDirectOrIndirectConflict(ConflictKind.PSEUDO)));
+ assertThat(differences, not(hasItem(hasDirectOrIndirectConflict(ConflictKind.REAL))));
+ }
+
+ /**
+ * Tests add-add conflict for a stereotype that defines attributes where all attributes on both sides are
+ * equal.
+ */
+ @Test
+ public void testApplyApplyPseudoConflictStereotypeWithAttributes() throws IOException {
+ final Comparison comparison = compare(input.getA2Left(), input.getA2Right(), input.getA2Base());
+ EList<Diff> differences = comparison.getDifferences();
+
+ assertThat(differences, hasItem(hasDirectOrIndirectConflict(ConflictKind.PSEUDO)));
+ assertThat(differences, not(hasItem(hasDirectOrIndirectConflict(ConflictKind.REAL))));
+ }
+
+ /**
+ * Tests add-add conflict for a stereotype that defines attributes where the two sides have different
+ * attribute values.
+ */
+ @Test
+ public void testApplyApplyConflictStereotypeWithAttributes() throws IOException {
+ final Comparison comparison = compare(input.getA3Left(), input.getA3Right(), input.getA3Base());
+ EList<Diff> differences = comparison.getDifferences();
+
+ assertThat(differences, hasItem(hasDirectOrIndirectConflict(ConflictKind.REAL)));
+ }
+
+ /**
+ * Tests add-add conflict for a stereotype that defines attributes where all attributes on both sides are
+ * equal.
+ */
+ @Test
+ public void testApplyApplyPseudoConflictStereotypeWithReferences() throws IOException {
+ final Comparison comparison = compare(input.getA4Left(), input.getA4Right(), input.getA4Base());
+ EList<Diff> differences = comparison.getDifferences();
+
+ assertThat(differences, hasItem(hasDirectOrIndirectConflict(ConflictKind.PSEUDO)));
+ assertThat(differences, not(hasItem(hasDirectOrIndirectConflict(ConflictKind.REAL))));
+ }
+
+ /**
+ * Tests add-add conflict for a stereotype that defines attributes where the two sides have different
+ * attribute values.
+ */
+ @Test
+ public void testApplyApplyConflictStereotypeWithReferences() throws IOException {
+ final Comparison comparison = compare(input.getA5Left(), input.getA5Right(), input.getA5Base());
+ EList<Diff> differences = comparison.getDifferences();
+
+ assertThat(differences, hasItem(hasDirectOrIndirectConflict(ConflictKind.REAL)));
+ }
+
+ /**
+ * Tests delete-delete pseudoconflict for a stereotype that is unapplied on both sides.
+ */
+ @Test
+ public void testUnpplyUnapplyPseudoconflictStereotypeWithAttributes() throws IOException {
+ final Comparison comparison = compare(input.getA6Left(), input.getA6Right(), input.getA6Base());
+ EList<Diff> differences = comparison.getDifferences();
+
+ assertThat(differences, hasItem(hasDirectOrIndirectConflict(ConflictKind.PSEUDO)));
+ }
+
+ //
+ // Test framework
+ //
+
+ @Override
+ protected AbstractUMLInputData getInput() {
+ return input;
+ }
+
+ @BeforeClass
+ public static void fillRegistriesForStatic() {
+ beforeClass();
+ if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
+ EPackage.Registry.INSTANCE.put(UML2CompareTestProfilePackage.eNS_URI,
+ UML2CompareTestProfilePackage.eINSTANCE);
+
+ // It is required to link the EPackage to the UML package of the UML Profile
+ Map<String, URI> ePackageNsURIToProfileLocationMap = UMLPlugin
+ .getEPackageNsURIToProfileLocationMap();
+ ePackageNsURIToProfileLocationMap.put(UML2CompareTestProfilePackage.eNS_URI, URI.createURI(
+ "pathmap://UML_COMPARE_TESTS_PROFILE/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"));
+ }
+ }
+
+ @AfterClass
+ public static void resetRegistriesForStatic() {
+ if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
+ UMLPlugin.getEPackageNsURIToProfileLocationMap().remove(UML2CompareTestProfilePackage.eNS_URI);
+ EPackage.Registry.INSTANCE.remove(UML2CompareTestProfilePackage.eNS_URI);
+ }
+ afterClass();
+ }
+
+ @Before
+ @Override
+ public void before() {
+ super.before();
+
+ input = new StereotypeApplicationConflictInputData();
+ }
+
+ static Matcher<Diff> hasDirectOrIndirectConflict(final ConflictKind... ofKind) {
+ return new TypeSafeMatcher<Diff>() {
+ public void describeTo(Description description) {
+ description.appendText("has ") //
+ .appendValueList("", " or ", "", ofKind) //
+ .appendText(" conflict");
+ }
+
+ @Override
+ protected boolean matchesSafely(Diff item) {
+ return EMFComparePredicates.hasDirectOrIndirectConflict(ofKind).apply(item);
+ }
+ };
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/StereotypeApplicationConflictInputData.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/StereotypeApplicationConflictInputData.java
new file mode 100644
index 000000000..c9d451c58
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/StereotypeApplicationConflictInputData.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Christian W. Damus 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:
+ * Christian W. Damus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.uml2.tests.stereotypes.data.conflict;
+
+import java.io.IOException;
+
+import org.eclipse.emf.compare.uml2.tests.AbstractUMLInputData;
+import org.eclipse.emf.ecore.resource.Resource;
+
+public class StereotypeApplicationConflictInputData extends AbstractUMLInputData {
+
+ public Resource getA1Base() throws IOException {
+ return loadFromClassLoader("a1/origin.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA1Left() throws IOException {
+ return loadFromClassLoader("a1/left.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA1Right() throws IOException {
+ return loadFromClassLoader("a1/right.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA2Base() throws IOException {
+ return loadFromClassLoader("a2/origin.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA2Left() throws IOException {
+ return loadFromClassLoader("a2/left.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA2Right() throws IOException {
+ return loadFromClassLoader("a2/right.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA3Base() throws IOException {
+ return loadFromClassLoader("a3/origin.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA3Left() throws IOException {
+ return loadFromClassLoader("a3/left.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA3Right() throws IOException {
+ return loadFromClassLoader("a3/right.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA4Base() throws IOException {
+ return loadFromClassLoader("a4/origin.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA4Left() throws IOException {
+ return loadFromClassLoader("a4/left.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA4Right() throws IOException {
+ return loadFromClassLoader("a4/right.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA5Base() throws IOException {
+ return loadFromClassLoader("a5/origin.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA5Left() throws IOException {
+ return loadFromClassLoader("a5/left.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA5Right() throws IOException {
+ return loadFromClassLoader("a5/right.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA6Base() throws IOException {
+ return loadFromClassLoader("a6/origin.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA6Left() throws IOException {
+ return loadFromClassLoader("a6/left.uml"); //$NON-NLS-1$
+ }
+
+ public Resource getA6Right() throws IOException {
+ return loadFromClassLoader("a6/right.uml"); //$NON-NLS-1$
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/left.uml
new file mode 100644
index 000000000..540c645e5
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/left.uml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:standard="http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_12E9QLjyEeeVg_HuOthLOA">
+ <eAnnotations xmi:id="_12E9QbjyEeeVg_HuOthLOA" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard#/"/>
+ </eAnnotations>
+ <appliedProfile href="pathmap://UML_PROFILES/Standard.profile.uml#_0"/>
+ </profileApplication>
+ </uml:Model>
+ <standard:Utility xmi:id="_7M_-oLjyEeeVg_HuOthLOA" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/origin.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/origin.uml
new file mode 100644
index 000000000..a236c69d7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/origin.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_12E9QLjyEeeVg_HuOthLOA">
+ <eAnnotations xmi:id="_12E9QbjyEeeVg_HuOthLOA" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard#/"/>
+ </eAnnotations>
+ <appliedProfile href="pathmap://UML_PROFILES/Standard.profile.uml#_0"/>
+ </profileApplication>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/right.uml
new file mode 100644
index 000000000..bad67919f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a1/right.uml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:standard="http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_12E9QLjyEeeVg_HuOthLOA">
+ <eAnnotations xmi:id="_12E9QbjyEeeVg_HuOthLOA" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard#/"/>
+ </eAnnotations>
+ <appliedProfile href="pathmap://UML_PROFILES/Standard.profile.uml#_0"/>
+ </profileApplication>
+ </uml:Model>
+ <standard:Utility xmi:id="_9GhFALjyEeeVg_HuOthLOA" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/left.uml
new file mode 100644
index 000000000..36db0c8e7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/left.uml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_lLJboPzmEeGvprorRl_paQ" singleValuedAttribute="bar" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/origin.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/origin.uml
new file mode 100644
index 000000000..9559588c1
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/origin.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/right.uml
new file mode 100644
index 000000000..a0f7622c0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a2/right.uml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_DgvBULjxEeeVg_HuOthLOA" singleValuedAttribute="bar" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/left.uml
new file mode 100644
index 000000000..9def561c9
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/left.uml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_lLJboPzmEeGvprorRl_paQ" singleValuedAttribute="baz" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/origin.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/origin.uml
new file mode 100644
index 000000000..9559588c1
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/origin.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/right.uml
new file mode 100644
index 000000000..a0f7622c0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a3/right.uml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_DgvBULjxEeeVg_HuOthLOA" singleValuedAttribute="bar" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/left.uml
new file mode 100644
index 000000000..c15a0e099
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/left.uml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_bv63ALmSEee3h-90p9bUpQ" name="Bar"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4ngALmSEee3h-90p9bUpQ" name="Baz"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_lLJboPzmEeGvprorRl_paQ" manyValuedReference="_bv63ALmSEee3h-90p9bUpQ _b4ngALmSEee3h-90p9bUpQ" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/origin.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/origin.uml
new file mode 100644
index 000000000..64fde5208
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/origin.uml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_bv63ALmSEee3h-90p9bUpQ" name="Bar"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4ngALmSEee3h-90p9bUpQ" name="Baz"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/right.uml
new file mode 100644
index 000000000..337652f5c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a4/right.uml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_bv63ALmSEee3h-90p9bUpQ" name="Bar"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4ngALmSEee3h-90p9bUpQ" name="Baz"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_DgvBULjxEeeVg_HuOthLOA" manyValuedReference="_bv63ALmSEee3h-90p9bUpQ _b4ngALmSEee3h-90p9bUpQ" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/left.uml
new file mode 100644
index 000000000..ee12fe3c0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/left.uml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_bv63ALmSEee3h-90p9bUpQ" name="Bar"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4ngALmSEee3h-90p9bUpQ" name="Baz"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_lLJboPzmEeGvprorRl_paQ" manyValuedReference="_b4ngALmSEee3h-90p9bUpQ _bv63ALmSEee3h-90p9bUpQ" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/origin.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/origin.uml
new file mode 100644
index 000000000..64fde5208
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/origin.uml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_bv63ALmSEee3h-90p9bUpQ" name="Bar"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4ngALmSEee3h-90p9bUpQ" name="Baz"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/right.uml
new file mode 100644
index 000000000..337652f5c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a5/right.uml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_bv63ALmSEee3h-90p9bUpQ" name="Bar"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_b4ngALmSEee3h-90p9bUpQ" name="Baz"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_DgvBULjxEeeVg_HuOthLOA" manyValuedReference="_bv63ALmSEee3h-90p9bUpQ _b4ngALmSEee3h-90p9bUpQ" base_Class="_MNDVkPr8EeCcXd0vrIzyPg"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/left.uml
new file mode 100644
index 000000000..9559588c1
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/left.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/origin.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/origin.uml
new file mode 100644
index 000000000..f3aaf88a2
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/origin.uml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:testProfile="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+ </uml:Model>
+ <testProfile:ACliche xmi:id="_lLJboPzmEeGvprorRl_paQ" singleValuedAttribute="baz" base_Class="_MNDVkPr8EeCcXd0vrIzyPg">
+ <manyValuedAttribute>foo</manyValuedAttribute>
+ <manyValuedAttribute>bar</manyValuedAttribute>
+ </testProfile:ACliche>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/right.uml
new file mode 100644
index 000000000..9559588c1
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/stereotypes/data/conflict/a6/right.uml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_GfO3Ifr8EeCcXd0vrIzyPg" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_MNDVkPr8EeCcXd0vrIzyPg" name="Foo"/>
+ <profileApplication xmi:id="_jAMnAPzmEeGvprorRl_paQ">
+ <eAnnotations xmi:id="_jAMnAfzmEeGvprorRl_paQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/compare/uml2/1.0.0/testprofile#/"/>
+ </eAnnotations>
+ <appliedProfile href="platform:/plugin/org.eclipse.emf.compare.uml2.tests/model/uml2.compare.testprofile.profile.uml#_hZFTgIwkEeC_FYHMbTTxXw"/>
+ </profileApplication>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java
index 752546d66..8f7e2552f 100644
--- a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2016 Obeo and others.
+ * Copyright (c) 2012, 2019 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
@@ -11,6 +11,7 @@
* Stefan Dirix - addition of PseudoConflictTest
* Martin Fleck - addition of RemoveStereotypeApplicationPseudoConflictTest
* Martin Fleck - addition of AddMessageSubDiffTest
+ * Christian W. Damus - bug 522080
*******************************************************************************/
package org.eclipse.emf.compare.uml2.tests.suite;
@@ -53,6 +54,7 @@ import org.eclipse.emf.compare.uml2.tests.stereotypes.DynamicStereotypeTest;
import org.eclipse.emf.compare.uml2.tests.stereotypes.DynamicStereotypedElementChangeTests;
import org.eclipse.emf.compare.uml2.tests.stereotypes.StaticStereotypeTest;
import org.eclipse.emf.compare.uml2.tests.stereotypes.StaticStereotypedElementChangeTests;
+import org.eclipse.emf.compare.uml2.tests.stereotypes.StereotypeApplicationConflictTests;
import org.eclipse.emf.compare.uml2.tests.timeConstraint.AddTimeConstraintTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -83,7 +85,8 @@ import junit.textui.TestRunner;
OpaqueElementBodyChangeDiffTest.class, OpaqueElementBodyChangeMergeTest.class,
DanglingStereotypeApplicationTest.class, TestNonRegPseudoConflict_484576.class,
RemoveStereotypeApplicationPseudoConflictTest.class, MultiplicityElementChangesTest.class,
- InstanceSpecificationClassifiersMergeTest.class, AddMessageSubDiffTest.class, })
+ InstanceSpecificationClassifiersMergeTest.class, AddMessageSubDiffTest.class,
+ StereotypeApplicationConflictTests.class, })
public class AllTests {
/**
diff --git a/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/StereotypedElementChangePostProcessor.java b/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/StereotypedElementChangePostProcessor.java
index 43be1311d..fd46f9df1 100644
--- a/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/StereotypedElementChangePostProcessor.java
+++ b/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/StereotypedElementChangePostProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Obeo.
+ * Copyright (c) 2014, 2019 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,15 +7,30 @@
*
* Contributors:
* Obeo - initial API and implementation
+ * Christian W. Damus - bug 522080
*******************************************************************************/
package org.eclipse.emf.compare.uml2.internal.postprocessor;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ComparisonCanceledException;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.diff.DefaultDiffEngine;
+import org.eclipse.emf.compare.diff.FeatureFilter;
import org.eclipse.emf.compare.postprocessor.IPostProcessor;
import org.eclipse.emf.compare.uml2.internal.postprocessor.extension.stereotype.UMLStereotypedElementChangeFactory;
+import org.eclipse.emf.compare.uml2.internal.postprocessor.util.UMLCompareUtil;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.uml2.uml.Element;
/**
* Post processor that creates the {@link org.eclipse.emf.compare.uml2.internal.StereotypedElementChange} in
@@ -36,6 +51,27 @@ public class StereotypedElementChangePostProcessor implements IPostProcessor {
* @see org.eclipse.emf.compare.postprocessor.IPostProcessor#postMatch(Comparison , Monitor)
*/
public void postMatch(Comparison comparison, Monitor monitor) {
+ // Re-match applications and unapplications of the same stereotypes to/from
+ // the same base elements
+ Map<Match, Map<URI, Match>> leftApplications = new HashMap<>();
+ Map<Match, Map<URI, Match>> rightApplications = new HashMap<>();
+ mapStereotypeApplications(comparison, leftApplications, rightApplications);
+
+ for (Map.Entry<Match, Map<URI, Match>> left : leftApplications.entrySet()) {
+ EObject base = left.getKey();
+ Map<URI, Match> right = rightApplications.get(base);
+ if (right != null) {
+ for (Map.Entry<URI, Match> next : left.getValue().entrySet()) {
+ Match rightMatch = right.get(next.getKey());
+ if (rightMatch != null) {
+ // Complete the left match
+ next.getValue().setRight(rightMatch.getRight());
+ // Drop the right match from the comparison
+ EcoreUtil.remove(rightMatch);
+ }
+ }
+ }
+ }
}
/**
@@ -43,7 +79,21 @@ public class StereotypedElementChangePostProcessor implements IPostProcessor {
*
* @see org.eclipse.emf.compare.postprocessor.IPostProcessor#postDiff(Comparison , Monitor)
*/
- public void postDiff(Comparison comparison, Monitor monitor) {
+ public void postDiff(final Comparison comparison, Monitor monitor) {
+ // We only need to do this for three-way comparisons to check for conflicts
+ // in stereotypes applied to the same elemnt on both sides but with different
+ // values
+ if (comparison.isThreeWay()) {
+ AttributeDiffEngine engine = new AttributeDiffEngine();
+ for (Match next : comparison.getMatches()) {
+ if (next.getOrigin() == null && next.getLeft() != null && next.getRight() != null) {
+ // Is it an add-add of a stereotype application?
+ if (isStereotypeApplication(next.getLeft())) {
+ engine.checkForDifferences(next, monitor);
+ }
+ }
+ }
+ }
}
/**
@@ -90,4 +140,174 @@ public class StereotypedElementChangePostProcessor implements IPostProcessor {
}
}
+ /**
+ * Compute maps of left- and right-side dangling matches of stereotype applications and unapplications.
+ * These map the {@link Match} for a base UML element to mappings of stereotypes (by {@link URI} of the
+ * definition) to matches for the stereotype application, itself.
+ *
+ * @param comparison
+ * the comparison in which to map stereotype application matches
+ * @param leftApplications
+ * the map of left-side matches to populate
+ * @param rightApplications
+ * the map of right-side matches to populate
+ */
+ protected void mapStereotypeApplications(Comparison comparison,
+ Map<Match, Map<URI, Match>> leftApplications, Map<Match, Map<URI, Match>> rightApplications) {
+ for (Match next : comparison.getMatches()) {
+ if (next.getLeft() != null && next.getRight() == null) {
+ // Unmatched left. Is it a stereotype application?
+ Match base = comparison.getMatch(getBaseElement(next.getLeft()));
+ if (base != null) {
+ // Map it
+ put(leftApplications, base, getStereotypeURI(next.getLeft()), next);
+ }
+ } else if (next.getRight() != null && next.getLeft() == null) {
+ // Unmatched right. Is it a stereotype application?
+ Match base = comparison.getMatch(getBaseElement(next.getRight()));
+ if (base != null) {
+ // Map it
+ put(rightApplications, base, getStereotypeURI(next.getRight()), next);
+ }
+ }
+ }
+ }
+
+ /**
+ * Obtains the URI of a stereotype application's type, for comparison independent of resource set context.
+ *
+ * @param stereotypeApplication
+ * a stereotype applicatkion
+ * @return the URI of its defining (stereo)type
+ */
+ private static URI getStereotypeURI(EObject stereotypeApplication) {
+ return EcoreUtil.getURI(stereotypeApplication.eClass());
+ }
+
+ /**
+ * Puts a value into a two-level map of maps.
+ *
+ * @param mapOfMaps
+ * the map
+ * @param key1
+ * the first level key
+ * @param key2
+ * the second level key
+ * @param value
+ * the value
+ * @return the previous value for these keys, if or {@code null} if there was none
+ * @param <K>
+ * the top level key type
+ * @param <L>
+ * the second level key type
+ * @param <V>
+ * the value type
+ */
+ private static <K, L, V> V put(Map<K, Map<L, V>> mapOfMaps, K key1, L key2, V value) {
+ Map<L, V> map = mapOfMaps.get(key1);
+ if (map == null) {
+ map = new HashMap<>();
+ mapOfMaps.put(key1, map);
+ }
+ return map.put(key2, value);
+ }
+
+ /**
+ * Queries whether an {@code object} is a stereotype application.
+ *
+ * @param object
+ * an object
+ * @return {@code true} if it is a stereotype application; {@code false}, otherwise
+ */
+ protected boolean isStereotypeApplication(EObject object) {
+ return getBaseElement(object) != null;
+ }
+
+ /**
+ * Gets the base element of an {@code object} if that a stereotype application.
+ *
+ * @param object
+ * an object
+ * @return its base element if it is a stereotype application; {@code null}, otherwise
+ */
+ protected Element getBaseElement(EObject object) {
+ Element result = null;
+
+ if (object.eContainer() == null) {
+ result = UMLCompareUtil.getBaseElement(object);
+ }
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ /**
+ * <p>
+ * Explicit diff engine for attributes of added stereotype applications.
+ * </p>
+ * <p>
+ * The default diff engine doesn't attempt to compare attributes of added elements. However, stereotype
+ * applications are special because they are extensions of other elements that are not added (because they
+ * would not be matched if the base elements were added, which in turn would not have been matched).
+ * </p>
+ */
+ protected class AttributeDiffEngine extends DefaultDiffEngine {
+ /**
+ * Initializes me.
+ */
+ public AttributeDiffEngine() {
+ super();
+ }
+
+ @Override
+ protected void checkForDifferences(Match match, Monitor monitor) {
+ if (monitor.isCanceled()) {
+ throw new ComparisonCanceledException();
+ }
+
+ final FeatureFilter featureFilter = createFeatureFilter();
+ final Iterator<EAttribute> attributes = featureFilter.getAttributesToCheck(match);
+ while (attributes.hasNext()) {
+ final EAttribute attribute = attributes.next();
+ final boolean considerOrdering = featureFilter.checkForOrderingChanges(attribute);
+ computeDifferences(match, attribute, considerOrdering);
+ }
+
+ for (Match submatch : match.getSubmatches()) {
+ checkForDifferences(submatch, monitor);
+ }
+ }
+
+ @Override
+ protected void computeDifferences(Match match, EAttribute attribute, boolean checkOrdering) {
+ // We *do* care about "attribute" changes on added stereotype applications,
+ // but not removed
+ boolean shortcut = match.getLeft() == null || match.getRight() == null;
+
+ // Do not shortcut when manyvalued FeatureMaps are affected to keep their ordering intact
+ if (shortcut && FeatureMapUtil.isFeatureMap(attribute)) {
+ if (FeatureMapUtil.isMany(match.getLeft(), attribute)) {
+ shortcut = false;
+ }
+ }
+
+ if (shortcut) {
+ return;
+ }
+
+ if (attribute.isMany()) {
+ if (match.getComparison().isThreeWay()) {
+ computeMultiValuedFeatureDifferencesThreeWay(match, attribute, checkOrdering);
+ } else {
+ computeMultiValuedFeatureDifferencesTwoWay(match, attribute, checkOrdering);
+ }
+ } else {
+ computeSingleValuedAttributeDifferences(match, attribute);
+ }
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/conflict/AbstractConflictSearch.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/conflict/AbstractConflictSearch.java
index 90592af95..aad205e26 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/conflict/AbstractConflictSearch.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/conflict/AbstractConflictSearch.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Obeo - initial API and implementation
+ * Christian W. Damus - bug 522080
*******************************************************************************/
package org.eclipse.emf.compare.internal.conflict;
@@ -186,7 +187,15 @@ public abstract class AbstractConflictSearch<T extends Diff> {
final String changedValue2 = getChangedValue(diff2);
final EObject originalContainer = diff1.getMatch().getOrigin();
final EAttribute changedAttribute = diff1.getAttribute();
- final String originalValue = (String)ReferenceUtil.safeEGet(originalContainer, changedAttribute);
+ final String originalValue;
+
+ if (originalContainer == null) {
+ // Owner is added to both sides
+ originalValue = null;
+ } else {
+ originalValue = (String)ReferenceUtil.safeEGet(originalContainer, changedAttribute);
+ }
+
return isMergeableText(changedValue1, changedValue2, originalValue);
}

Back to the top