Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Langer2016-12-05 18:12:24 +0000
committerPhilip Langer2017-01-13 15:21:23 +0000
commitda4e46807e9aa5bc102dbc5fc073a162137b6405 (patch)
treecf650d9b60e5c948e0a21a2c225a7610124d6c0b
parent8729a641e78b15269342124f3b375084c8afbea7 (diff)
downloadorg.eclipse.emf.compare-da4e46807e9aa5bc102dbc5fc073a162137b6405.tar.gz
org.eclipse.emf.compare-da4e46807e9aa5bc102dbc5fc073a162137b6405.tar.xz
org.eclipse.emf.compare-da4e46807e9aa5bc102dbc5fc073a162137b6405.zip
[508665] Delete EnumerationLiteral classifier changes from comparison
EnumerationLiteral.classifier is essentially a derived feature. In fact, the classifier of an EnumerationLiteral is always its containing Enumeration. However, this feature is not declared as such in the metamodel, as it is inherited from InstanceSpecification.classifier, which is not derived. In the UML implementation, EnumerationLiteral.classifier, therefore, overwrites InstanceSpecification.classifier to return an unmodifiable collection always containing the Enumeration instead of a writable collection. Thus, we have to avoid merging changes of EnumerationLiteral.classifier changes and can ignore changes of this feature altogether. Changes of this feature on EnumerationLiterals will therefore be deleted, just as if it would have been the case if the feature would really be declared as derived feature. Bug: 508665 Change-Id: I685e5ab6ef29c3c452845e4f9deae087a9b3b40b Signed-off-by: Philip Langer <planger@eclipsesource.com>
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/internal/utils/ComparisonUtilDeleteTest.java131
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java5
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/InstanceSpecificationClassifiersMergeTest.java160
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/InstanceSpecificationClassifiersMergeInputData.java59
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/left.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/right.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/left.uml10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/right.uml8
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/left.uml11
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/right.uml11
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/left.uml11
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/right.uml11
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java15
-rw-r--r--plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/UMLPostProcessor.java61
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/ComparisonUtil.java31
15 files changed, 532 insertions, 12 deletions
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/internal/utils/ComparisonUtilDeleteTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/internal/utils/ComparisonUtilDeleteTest.java
new file mode 100644
index 000000000..4aa66e4d4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/internal/utils/ComparisonUtilDeleteTest.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * 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:
+ * Philip Langer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.internal.utils;
+
+import static org.eclipse.emf.compare.DifferenceSource.LEFT;
+import static org.eclipse.emf.compare.DifferenceSource.RIGHT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Conflict;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.Equivalence;
+import org.eclipse.emf.compare.Match;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ComparisonUtilDeleteTest {
+
+ private static final CompareFactory COMPARE_FACTORY = CompareFactory.eINSTANCE;
+
+ private Match match;
+
+ private Diff diffToDelete;
+
+ @Before
+ public void setUp() {
+ match = createMatch(COMPARE_FACTORY.createComparison());
+ diffToDelete = createDiff(LEFT);
+ }
+
+ private Match createMatch(Comparison comparison) {
+ Match newMatch = COMPARE_FACTORY.createMatch();
+ comparison.getMatches().add(newMatch);
+ return newMatch;
+ }
+
+ private Diff createDiff(DifferenceSource side) {
+ Diff newDiff = COMPARE_FACTORY.createDiff();
+ match.getDifferences().add(newDiff);
+ newDiff.setSource(side);
+ return newDiff;
+ }
+
+ private Conflict createConflict(Diff... diffs) {
+ Conflict newConflict = COMPARE_FACTORY.createConflict();
+ newConflict.getDifferences().addAll(Arrays.asList(diffs));
+ match.getComparison().getConflicts().add(newConflict);
+ return newConflict;
+ }
+
+ private Equivalence createEquivalence(Diff... diffs) {
+ Equivalence newEquivalence = COMPARE_FACTORY.createEquivalence();
+ newEquivalence.getDifferences().addAll(Arrays.asList(diffs));
+ match.getComparison().getEquivalences().add(newEquivalence);
+ return newEquivalence;
+ }
+
+ @Test
+ public void testDeleteDiff() {
+ ComparisonUtil.delete(diffToDelete);
+ assertFalse(match.getDifferences().contains(diffToDelete));
+ }
+
+ @Test
+ public void testDeleteDiff_WithConflictsToDelete() {
+ final Diff conflictingDiff = createDiff(RIGHT);
+ Conflict conflictToDelete = createConflict(diffToDelete, conflictingDiff);
+ Conflict otherConflict = createConflict(createDiff(LEFT), createDiff(RIGHT));
+ ComparisonUtil.delete(diffToDelete);
+
+ assertFalse(match.getDifferences().contains(diffToDelete));
+ assertNull(conflictingDiff.getConflict());
+ assertFalse(match.getComparison().getConflicts().contains(conflictToDelete));
+ assertTrue(match.getComparison().getConflicts().contains(otherConflict));
+ assertEquals(2, otherConflict.getDifferences().size());
+ }
+
+ @Test
+ public void testDeleteDiff_WithConflictToKeep() {
+ Conflict conflictToKeep = createConflict(diffToDelete, createDiff(LEFT), createDiff(RIGHT));
+ ComparisonUtil.delete(diffToDelete);
+
+ assertFalse(match.getDifferences().contains(diffToDelete));
+ assertFalse(conflictToKeep.getDifferences().contains(diffToDelete));
+
+ assertTrue(match.getComparison().getConflicts().contains(conflictToKeep));
+ assertEquals(1, conflictToKeep.getLeftDifferences().size());
+ assertEquals(1, conflictToKeep.getRightDifferences().size());
+ }
+
+ @Test
+ public void testDeleteDiff_WithEquivalencesToDelete() {
+ Diff equivalentDiff = createDiff(RIGHT);
+ Equivalence equivalenceToDelete = createEquivalence(diffToDelete, equivalentDiff);
+ Equivalence otherEquivalence = createEquivalence(createDiff(LEFT), createDiff(RIGHT));
+ ComparisonUtil.delete(diffToDelete);
+
+ assertFalse(match.getDifferences().contains(diffToDelete));
+ assertNull(equivalentDiff.getEquivalence());
+ assertFalse(match.getComparison().getEquivalences().contains(equivalenceToDelete));
+ assertTrue(match.getComparison().getEquivalences().contains(otherEquivalence));
+ assertEquals(2, otherEquivalence.getDifferences().size());
+ }
+
+ @Test
+ public void testDeleteDiff_WithEquivalenceToKeep() {
+ Equivalence equivalenceToKeep = createEquivalence(diffToDelete, createDiff(LEFT), createDiff(RIGHT));
+ ComparisonUtil.delete(diffToDelete);
+
+ assertFalse(match.getDifferences().contains(diffToDelete));
+ assertFalse(equivalenceToKeep.getDifferences().contains(diffToDelete));
+
+ assertTrue(match.getComparison().getEquivalences().contains(equivalenceToKeep));
+ assertEquals(2, equivalenceToKeep.getDifferences().size());
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
index 8e093a4b3..606545ac6 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2016 Obeo and others.
+ * Copyright (c) 2012, 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
@@ -98,7 +98,8 @@ import junit.textui.TestRunner;
MultiLineAttributeMergeTest.class, MonitorCancelTest.class, IdentifierEObjectMatcherTest.class,
MatchUtilFeatureContainsTest.class, RefineMergeTest.class, Bug484557ConflictTest.class,
Bug485266_MoveDeleteConflict_Test.class, ResourceAttachmentChangeBug492261.class,
- ComparisonScopeAdapterTest.class, EMFComparePredicatesTest.class, RankedAdapterFactoryRegistryTest.class })
+ ComparisonScopeAdapterTest.class, EMFComparePredicatesTest.class,
+ RankedAdapterFactoryRegistryTest.class, ComparisonUtilTest.class, })
public class AllTests {
/**
* Standalone launcher for all of compare's tests.
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/InstanceSpecificationClassifiersMergeTest.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/InstanceSpecificationClassifiersMergeTest.java
new file mode 100644
index 000000000..ec60a99f2
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/InstanceSpecificationClassifiersMergeTest.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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:
+ * Philip Langer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.uml2.tests.merge;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import org.eclipse.emf.compare.uml2.tests.AbstractUMLInputData;
+import org.eclipse.emf.compare.uml2.tests.AbstractUMLTest;
+import org.eclipse.emf.compare.uml2.tests.merge.data.InstanceSpecificationClassifiersMergeInputData;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.uml2.uml.EnumerationLiteral;
+import org.eclipse.uml2.uml.InstanceSpecification;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests merging changes of the feature {@link InstanceSpecification#getClassifiers()}.
+ * <p>
+ * Merging {@link InstanceSpecification#getClassifiers()} requires special handling, if the instance
+ * specification is an {@link EnumerationLiteral}, because {@link EnumerationLiteral} overwrites
+ * {@link InstanceSpecification#getClassifiers()}, so that it returns an unmodifiable UnionEObjectEList, which
+ * always contains the Enumeration as item. Thus, we have to handle changes of
+ * {@link EnumerationLiteral#getClassifiers()} as if this feature would be derived.
+ * </p>
+ * <p>
+ * See also <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=508665">bug 508665</a>.
+ * </p>
+ *
+ * @author Philip Langer <planger@eclipsesource.com>
+ */
+public class InstanceSpecificationClassifiersMergeTest extends AbstractUMLTest {
+
+ private InstanceSpecificationClassifiersMergeInputData input = new InstanceSpecificationClassifiersMergeInputData();
+
+ @Override
+ protected AbstractUMLInputData getInput() {
+ return input;
+ }
+
+ @BeforeClass
+ public static void setupClass() {
+ fillRegistries();
+ }
+
+ @AfterClass
+ public static void teardownClass() {
+ resetRegistries();
+ }
+
+ /**
+ * Tests merging a move an enumeration literal from one enumeration to another.
+ * <p>
+ * The model contains two enumerations, <i>Enumeration1</i> and <i>Enumeration2</i>. On the left-hand
+ * side, <i>Enumeration1</i> contains a literal. On the right-hand side, this literal is contained by
+ * <i>Enumeration2</i> instead. This test merges in both directions.
+ * </p>
+ *
+ * @throws IOException
+ * Thrown if example model could not be read.
+ */
+ @Test
+ public void testMergeOfMovedEnumerationLiteral() throws IOException {
+ final Resource left = input.getInstanceSpec1Left();
+ final Resource right = input.getInstanceSpec1Right();
+ testMergeBothDirections(left, right);
+ }
+
+ /**
+ * Tests merging a the addition / deletion of an enumeration literal.
+ * <p>
+ * The model contains two enumerations, <i>Enumeration1</i> and <i>Enumeration2</i>. On the left-hand
+ * side, <i>Enumeration1</i> contains an enumeration literal. On the right-hand side, it doesn't. This
+ * test merges in both directions to test the addition and the deletion in the merger.
+ * </p>
+ *
+ * @throws IOException
+ * Thrown if example model could not be read.
+ */
+ @Test
+ public void testMergeOfAddedOrDeletedEnumerationLiteral() throws IOException {
+ final Resource left = input.getInstanceSpec2Left();
+ final Resource right = input.getInstanceSpec2Right();
+ testMergeBothDirections(left, right);
+ }
+
+ /**
+ * Tests merging a the addition / deletion of an instance specification's classifier.
+ * <p>
+ * The intention of this test is to make sure that we don't break the correct merging of normal instance
+ * specification classifiers, while still support correctly merging
+ * {@link EnumerationLiteral#getClassifier()}.
+ * </p>
+ * <p>
+ * The model contains two enumerations, <i>Enumeration1</i> and <i>Enumeration2</i>, and an instance
+ * specification. On the left-hand side, <i>Enumeration1</i> is a classifier of the instance
+ * specification. On the right-hand side, it doesn't. This test merges in both directions to test the
+ * addition and the deletion in the merger.
+ * </p>
+ *
+ * @throws IOException
+ * Thrown if example model could not be read.
+ */
+ @Test
+ public void testMergeOfAddedOrDeletedInstanceSpecificationClassifier() throws IOException {
+ final Resource left = input.getInstanceSpec3Left();
+ final Resource right = input.getInstanceSpec3Right();
+ testMergeBothDirections(left, right);
+ }
+
+ /**
+ * Tests merging a the change of an instance specification's classifier.
+ * <p>
+ * The intention of this test is to make sure that we don't break the correct merging of normal instance
+ * specification classifiers, while still support correctly merging
+ * {@link EnumerationLiteral#getClassifier()}.
+ * </p>
+ * <p>
+ * The model contains two enumerations, <i>Enumeration1</i> and <i>Enumeration2</i>, and an instance
+ * specification. On the left-hand side, <i>Enumeration1</i> is a classifier of the instance
+ * specification. On the right-hand side, the instance specification's classifier is <i>Enumeration2</i>.
+ * This test merges in both directions to test the addition and the deletion in the merger.
+ * </p>
+ *
+ * @throws IOException
+ * Thrown if example model could not be read.
+ */
+ @Test
+ public void testMergeOfChangedInstanceSpecificationClassifier() throws IOException {
+ final Resource left = input.getInstanceSpec4Left();
+ final Resource right = input.getInstanceSpec4Right();
+ testMergeBothDirections(left, right);
+ }
+
+ private void testMergeBothDirections(Resource left, Resource right) throws IOException {
+ testMergeLeftToRight(left, right, null);
+ reload(left, right);
+ testMergeRightToLeft(left, right, null);
+ reload(left, right);
+ testMergeLeftToRight(right, left, null);
+ reload(left, right);
+ testMergeRightToLeft(right, left, null);
+ }
+
+ private void reload(Resource... resources) throws IOException {
+ for (Resource resource : resources) {
+ resource.unload();
+ resource.load(Collections.EMPTY_MAP);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/InstanceSpecificationClassifiersMergeInputData.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/InstanceSpecificationClassifiersMergeInputData.java
new file mode 100644
index 000000000..a5d9b84c9
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/InstanceSpecificationClassifiersMergeInputData.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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:
+ * Philip Langer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.uml2.tests.merge.data;
+
+import java.io.IOException;
+
+import org.eclipse.emf.compare.uml2.tests.AbstractUMLInputData;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.uml2.uml.resources.util.UMLResourcesUtil;
+
+public class InstanceSpecificationClassifiersMergeInputData extends AbstractUMLInputData {
+ public Resource getInstanceSpec1Left() throws IOException {
+ return loadFromClassLoader("instancespec1/left.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ public Resource getInstanceSpec1Right() throws IOException {
+ return loadFromClassLoader("instancespec1/right.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ public Resource getInstanceSpec2Left() throws IOException {
+ return loadFromClassLoader("instancespec2/left.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ public Resource getInstanceSpec2Right() throws IOException {
+ return loadFromClassLoader("instancespec2/right.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ public Resource getInstanceSpec3Left() throws IOException {
+ return loadFromClassLoader("instancespec3/left.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ public Resource getInstanceSpec3Right() throws IOException {
+ return loadFromClassLoader("instancespec3/right.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ public Resource getInstanceSpec4Left() throws IOException {
+ return loadFromClassLoader("instancespec4/left.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ public Resource getInstanceSpec4Right() throws IOException {
+ return loadFromClassLoader("instancespec4/right.uml", createResourceSet()); //$NON-NLS-1$
+ }
+
+ private ResourceSet createResourceSet() {
+ final ResourceSet resourceSet = new ResourceSetImpl();
+ UMLResourcesUtil.init(resourceSet);
+ return resourceSet;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/left.uml
new file mode 100644
index 000000000..084a72aa9
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/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:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1">
+ <ownedLiteral xmi:type="uml:EnumerationLiteral" xmi:id="_literal1" name="Literal1"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2" />
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/right.uml
new file mode 100644
index 000000000..b5a2a8705
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec1/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:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1" />
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2">
+ <ownedLiteral xmi:type="uml:EnumerationLiteral" xmi:id="_literal1" name="Literal1"/>
+ </packagedElement>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/left.uml
new file mode 100644
index 000000000..084a72aa9
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/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:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1">
+ <ownedLiteral xmi:type="uml:EnumerationLiteral" xmi:id="_literal1" name="Literal1"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2" />
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/right.uml
new file mode 100644
index 000000000..f78268a8e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec2/right.uml
@@ -0,0 +1,8 @@
+<?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="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1" />
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2" />
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/left.uml
new file mode 100644
index 000000000..ad9ef3f35
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/left.uml
@@ -0,0 +1,11 @@
+<?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="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1">
+ <ownedLiteral xmi:type="uml:EnumerationLiteral" xmi:id="_literal1" name="Literal1"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2" />
+ <packagedElement xmi:type="uml:InstanceSpecification" xmi:id="_instanceSpecification" name="InstanceSpecification" classifier="_enumeration1"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/right.uml
new file mode 100644
index 000000000..b01c02219
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec3/right.uml
@@ -0,0 +1,11 @@
+<?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="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1">
+ <ownedLiteral xmi:type="uml:EnumerationLiteral" xmi:id="_literal1" name="Literal1"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2" />
+ <packagedElement xmi:type="uml:InstanceSpecification" xmi:id="_instanceSpecification" name="InstanceSpecification"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/left.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/left.uml
new file mode 100644
index 000000000..ad9ef3f35
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/left.uml
@@ -0,0 +1,11 @@
+<?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="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1">
+ <ownedLiteral xmi:type="uml:EnumerationLiteral" xmi:id="_literal1" name="Literal1"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2" />
+ <packagedElement xmi:type="uml:InstanceSpecification" xmi:id="_instanceSpecification" name="InstanceSpecification" classifier="_enumeration1"/>
+</uml:Model>
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/right.uml b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/right.uml
new file mode 100644
index 000000000..5dac7dab7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/data/instancespec4/right.uml
@@ -0,0 +1,11 @@
+<?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="_rootElement" name="RootElement">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_packageImport">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration1" name="Enumeration1">
+ <ownedLiteral xmi:type="uml:EnumerationLiteral" xmi:id="_literal1" name="Literal1"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Enumeration" xmi:id="_enumeration2" name="Enumeration2" />
+ <packagedElement xmi:type="uml:InstanceSpecification" xmi:id="_instanceSpecification" name="InstanceSpecification" classifier="_enumeration2"/>
+</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 e00e2bca8..5774a8526 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, 2015 Obeo and others.
+ * Copyright (c) 2012, 2016 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,16 +7,12 @@
*
* Contributors:
* Obeo - initial API and implementation
- * Philip Langer - addition of OpaqueTest
+ * Philip Langer - addition of OpaqueTest, ImplicationsInstanceSpecificationClassifiersTest
* Stefan Dirix - addition of PseudoConflictTest
* Martin Fleck - addition of RemoveStereotypeApplicationPseudoConflictTest
*******************************************************************************/
package org.eclipse.emf.compare.uml2.tests.suite;
-import junit.framework.JUnit4TestAdapter;
-import junit.framework.Test;
-import junit.textui.TestRunner;
-
import org.eclipse.emf.compare.uml2.tests.association.AddAssociation2Test;
import org.eclipse.emf.compare.uml2.tests.association.AddAssociation3Test;
import org.eclipse.emf.compare.uml2.tests.association.AddAssociationTest;
@@ -41,6 +37,7 @@ import org.eclipse.emf.compare.uml2.tests.implications.ImplicationsInterfaceReal
import org.eclipse.emf.compare.uml2.tests.implications.ImplicationsTransitionTest;
import org.eclipse.emf.compare.uml2.tests.include.AddIncludeTest;
import org.eclipse.emf.compare.uml2.tests.merge.ExtensionMergeTest;
+import org.eclipse.emf.compare.uml2.tests.merge.InstanceSpecificationClassifiersMergeTest;
import org.eclipse.emf.compare.uml2.tests.merge.MergeDiffInvolvingRefineDiffTest;
import org.eclipse.emf.compare.uml2.tests.message.AddMessageTest;
import org.eclipse.emf.compare.uml2.tests.multiplicitychanges.MultiplicityElementChangesTest;
@@ -60,6 +57,10 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import junit.textui.TestRunner;
+
/**
* This test suite allows us to launch all tests for EMF Compare at once.
*
@@ -81,7 +82,7 @@ import org.junit.runners.Suite.SuiteClasses;
OpaqueElementBodyChangeDiffTest.class, OpaqueElementBodyChangeMergeTest.class,
DanglingStereotypeApplicationTest.class, MergeDiffInvolvingRefineDiffTest.class,
TestNonRegPseudoConflict_484576.class, RemoveStereotypeApplicationPseudoConflictTest.class,
- MultiplicityElementChangesTest.class })
+ MultiplicityElementChangesTest.class, InstanceSpecificationClassifiersMergeTest.class, })
public class AllTests {
/**
diff --git a/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/UMLPostProcessor.java b/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/UMLPostProcessor.java
index 1917d799e..379ddea4a 100644
--- a/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/UMLPostProcessor.java
+++ b/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/internal/postprocessor/UMLPostProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2015 Obeo.
+ * Copyright (c) 2012, 2016 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,11 +8,14 @@
* Contributors:
* Obeo - initial API and implementation
* Martin Fleck - Consider profile definition changes on origin (bug 495259)
+ * Philip Langer - bug 508665
*******************************************************************************/
package org.eclipse.emf.compare.uml2.internal.postprocessor;
+import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.delete;
import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.isAddOrSetDiff;
import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.isDeleteOrUnsetDiff;
+import static org.eclipse.uml2.uml.UMLPackage.Literals.INSTANCE_SPECIFICATION__CLASSIFIER;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@@ -51,6 +54,8 @@ import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.ProfileApplication;
/**
@@ -301,9 +306,12 @@ public class UMLPostProcessor implements IPostProcessor {
}
// Filling implications with subsets
+ // And delete enumeration literal classifier changes, as it is actually a derived feature
for (Diff diff : comparison.getDifferences()) {
if (diff instanceof ReferenceChange) {
- fillImplicationsWithUMLSubsets((ReferenceChange)diff);
+ final ReferenceChange referenceChange = (ReferenceChange)diff;
+ fillImplicationsWithUMLSubsets(referenceChange);
+ deleteEnumerationLiteralClassifierChanges(referenceChange);
}
}
@@ -385,4 +393,53 @@ public class UMLPostProcessor implements IPostProcessor {
}
}
}
+
+ /**
+ * Deletes the given <code>referenceChange</code>, if it is an {@link EnumerationLiteral#getClassifier()
+ * enumeration literal classifier} change.
+ *
+ * @param referenceChange
+ * The reference change to check and delete.
+ */
+ private void deleteEnumerationLiteralClassifierChanges(ReferenceChange referenceChange) {
+ if (isEnumerationLiteralClassifierChange(referenceChange)) {
+ delete(referenceChange);
+ }
+ }
+
+ /**
+ * Specifies whether the given <code>referenceChange</code> is a change of an
+ * {@link EnumerationLiteral#getClassifier() enumeration literal classifier}, whereas the type of the
+ * reference change's value must be Enumeration.
+ *
+ * @param referenceChange
+ * The reference change to check.
+ * @return <code>true</code> if it is a EnumerationLiteral classifier change, <code>false</code>
+ * otherwise.
+ */
+ private boolean isEnumerationLiteralClassifierChange(ReferenceChange referenceChange) {
+ return INSTANCE_SPECIFICATION__CLASSIFIER.equals(referenceChange.getReference())
+ && getAnyMatchedEObject(referenceChange) instanceof EnumerationLiteral
+ && referenceChange.getValue() instanceof Enumeration;
+ }
+
+ /**
+ * Returns the left-, right-, or origin object of the given <code>diff</code>'s match.
+ *
+ * @param diff
+ * The diff to get the matched object for.
+ * @return The matched object of any side.
+ */
+ private EObject getAnyMatchedEObject(Diff diff) {
+ final Match match = diff.getMatch();
+ final EObject eObject;
+ if (match.getLeft() != null) {
+ eObject = match.getLeft();
+ } else if (match.getRight() != null) {
+ eObject = match.getRight();
+ } else {
+ eObject = match.getOrigin();
+ }
+ return eObject;
+ }
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/ComparisonUtil.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/ComparisonUtil.java
index e53e34f46..1067ffee4 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/ComparisonUtil.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/ComparisonUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2016 Obeo and others.
+ * Copyright (c) 2012, 2017 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
* Stefan Dirix - added #getExpectedSide
+ * Philip Langer - added #delete(Diff)
*******************************************************************************/
package org.eclipse.emf.compare.internal.utils;
@@ -55,6 +56,7 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.util.FeatureMap;
@@ -624,4 +626,31 @@ public final class ComparisonUtil {
}
return false;
}
+
+ /**
+ * {@link EcoreUtil#delete(EObject) Deletes} the given <code>diff</code>.
+ * <p>
+ * Conflicts and equivalences of the <code>diff</code> will also be removed if they get meaningless after
+ * the <code>diff</code> has been deleted. A conflict is meaningless, if it has diffs only on one side
+ * after the deletion. An equivalence is meaningless, if it has only one diff left.
+ * </p>
+ *
+ * @param diff
+ * The diff to delete.
+ */
+ public static void delete(Diff diff) {
+ final Comparison comparison = diff.getMatch().getComparison();
+ final Conflict conflict = diff.getConflict();
+ final Equivalence equivalence = diff.getEquivalence();
+ EcoreUtil.delete(diff);
+ if (conflict != null
+ && (conflict.getLeftDifferences().isEmpty() || conflict.getRightDifferences().isEmpty())) {
+ conflict.getDifferences().clear();
+ comparison.getConflicts().remove(conflict);
+ }
+ if (equivalence != null && equivalence.getDifferences().size() < 2) {
+ equivalence.getDifferences().clear();
+ comparison.getEquivalences().remove(equivalence);
+ }
+ }
}

Back to the top