Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Dirix2015-02-18 13:17:49 +0000
committerAxel Richard2015-03-02 14:15:35 +0000
commit01ea4a0e47ca488514e9556921bfb343d2b25504 (patch)
tree40ff2ea918d5a7dab8407f2a3e8a2ec039406b9e
parent0d5159b09e90fc218583fd321922040cdcea3545 (diff)
downloadorg.eclipse.emf.compare-01ea4a0e47ca488514e9556921bfb343d2b25504.tar.gz
org.eclipse.emf.compare-01ea4a0e47ca488514e9556921bfb343d2b25504.tar.xz
org.eclipse.emf.compare-01ea4a0e47ca488514e9556921bfb343d2b25504.zip
[460675] Fix differences for noncontained FeatureMapEntries with moved
values Fixes the calculation of differences in scenarios where a non-contained entry is added to (or removed from) a FeatureMap and its reference is simultaneously moved. Includes testcases. Bug: 460675 Signed-off-by: Stefan Dirix <sdirix@eclipsesource.com> Change-Id: I0c10a907f3bf3d2aaf857ac799cbe81967d23249
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java32
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java18
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/left.nodes8
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/right.nodes8
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/left.nodes7
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/right.nodes9
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/diff/DefaultDiffEngine.java25
7 files changed, 94 insertions, 13 deletions
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java
index 22a2e4778..f01c07b5e 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TwoWayBatchMergingTest.java
@@ -8,7 +8,7 @@
* Contributors:
* Philip Langer - initial API and implementation
* Alexandra Buzila - Test case for bug 446252
- * Stefan Dirix - Test case for bug 453749
+ * Stefan Dirix - Test cases for bugs 453749 and 460675
*******************************************************************************/
package org.eclipse.emf.compare.tests.merge;
@@ -205,6 +205,36 @@ public class TwoWayBatchMergingTest {
}
/**
+ * Tests a scenario in which a non-containment feature map key is removed and the node to which it refers
+ * is moved.
+ *
+ * @throws IOException
+ * if {@link TwoWayMergeInputData} fails to load the test models.
+ */
+ @Test
+ public void mergingFeatureMapKeyRemoveAndRefMoveL2R() throws IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ final Resource left = input.getFeatureMapKeyRemoveAndRefMoveL2RLeft(resourceSet);
+ final Resource right = input.getFeatureMapKeyRemoveAndRefMoveL2RRight(resourceSet);
+ batchMergeAndAssertEquality(left, right, Direction.LEFT_TO_RIGHT);
+ }
+
+ /**
+ * Tests a scenario in which a non-containment feature map key is added and the node to which it refers is
+ * moved.
+ *
+ * @throws IOException
+ * if {@link TwoWayMergeInputData} fails to load the test models.
+ */
+ @Test
+ public void mergingFeatureMapKeyAddAndRefMoveR2L() throws IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ final Resource left = input.getFeatureMapKeyAddAndRefMoveR2LLeft(resourceSet);
+ final Resource right = input.getFeatureMapKeyAddAndRefMoveR2LRight(resourceSet);
+ batchMergeAndAssertEquality(left, right, Direction.RIGHT_TO_LEFT);
+ }
+
+ /**
* Tests a scenario in which a feature map contains multiple references to the same node without
* containing it. It is tested if the merger can correctly delete some of these references.
*
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java
index 5f84f8abb..f45222c33 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/TwoWayMergeInputData.java
@@ -8,7 +8,7 @@
* Contributors:
* Philip Langer - initial API and implementation
* Alexandra Buzila - test data for bug 446252
- * Stefan Dirix - test data for bugs 452147, 453749, 460902 and 460923
+ * Stefan Dirix - test data for bugs 452147, 453749, 460902, 460923 and 460975
*******************************************************************************/
package org.eclipse.emf.compare.tests.merge.data;
@@ -84,6 +84,22 @@ public class TwoWayMergeInputData extends AbstractInputData {
return loadFromClassLoader("twoway/movetofeaturemap/ltr/right.nodes");
}
+ public Resource getFeatureMapKeyRemoveAndRefMoveL2RLeft(ResourceSet resourceSet) throws IOException {
+ return loadFromClassLoader("twoway/featuremapkeyremoveandrefmove/ltr/left.nodes", resourceSet);
+ }
+
+ public Resource getFeatureMapKeyRemoveAndRefMoveL2RRight(ResourceSet resourceSet) throws IOException {
+ return loadFromClassLoader("twoway/featuremapkeyremoveandrefmove/ltr/right.nodes", resourceSet);
+ }
+
+ public Resource getFeatureMapKeyAddAndRefMoveR2LLeft(ResourceSet resourceSet) throws IOException {
+ return loadFromClassLoader("twoway/featuremapkeyaddandrefmove/rtl/left.nodes", resourceSet);
+ }
+
+ public Resource getFeatureMapKeyAddAndRefMoveR2LRight(ResourceSet resourceSet) throws IOException {
+ return loadFromClassLoader("twoway/featuremapkeyaddandrefmove/rtl/right.nodes", resourceSet);
+ }
+
public Resource getDeleteFeatureMapNonContainmentsL2RLeft(ResourceSet resourceSet) throws IOException {
return loadFromClassLoader("twoway/deletefeaturemapnoncontainments/ltr/left.nodes", resourceSet);
}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/left.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/left.nodes
new file mode 100644
index 000000000..518cccf07
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/left.nodes
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ASCII"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" name="Root">
+ <containmentRef1 xsi:type="nodes:NodeFeatureMapNonContainment" name="n" xmi:id="_n">
+ <firstKeyNC href="#_q"/>
+ </containmentRef1>
+ <containmentRef1 xsi:type="nodes:Node" name="r" xmi:id="_r"/>
+ <containmentRef1 xsi:type="nodes:Node" name="q" xmi:id="_q"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/right.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/right.nodes
new file mode 100644
index 000000000..9002ad053
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyaddandrefmove/rtl/right.nodes
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ASCII"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" name="Root">
+ <containmentRef1 xsi:type="nodes:NodeFeatureMapNonContainment" name="n" xmi:id="_n">
+ </containmentRef1>
+ <containmentRef1 xsi:type="nodes:Node" name="r" xmi:id="_r">
+ <containmentRef1 xsi:type="nodes:Node" name="q" xmi:id="_q"/>
+ </containmentRef1>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/left.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/left.nodes
new file mode 100644
index 000000000..97b2bb545
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/left.nodes
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ASCII"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" name="Root">
+ <containmentRef1 xsi:type="nodes:NodeFeatureMapNonContainment" name="n" xmi:id="_n">
+ </containmentRef1>
+ <containmentRef1 xsi:type="nodes:Node" name="r" xmi:id="_r"/>
+ <containmentRef1 xsi:type="nodes:Node" name="q" xmi:id="_q"/>
+</nodes:Node> \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/right.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/right.nodes
new file mode 100644
index 000000000..11298588c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/data/twoway/featuremapkeyremoveandrefmove/ltr/right.nodes
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ASCII"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" name="Root">
+ <containmentRef1 xsi:type="nodes:NodeFeatureMapNonContainment" name="n" xmi:id="_n">
+ <firstKeyNC href="#_q"/>
+ </containmentRef1>
+ <containmentRef1 xsi:type="nodes:Node" name="r" xmi:id="_r">
+ <containmentRef1 xsi:type="nodes:Node" name="q" xmi:id="_q"/>
+ </containmentRef1>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/diff/DefaultDiffEngine.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/diff/DefaultDiffEngine.java
index 00a8a2b28..24a45d18d 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/diff/DefaultDiffEngine.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/diff/DefaultDiffEngine.java
@@ -7,7 +7,7 @@
*
* Contributors:
* Obeo - initial API and implementation
- * Stefan Dirix - Bugs 450949, 453218 and 460923
+ * Stefan Dirix - Bugs 450949, 453218, 460923 and 460675
*******************************************************************************/
package org.eclipse.emf.compare.diff;
@@ -632,7 +632,7 @@ public class DefaultDiffEngine implements IDiffEngine {
// A value of a FeatureMap changed his key
if (isFeatureMapEntryKeyChange(equality, (FeatureMap.Entry)diffCandidate, originValues)) {
featureChange(match, feature, diffCandidate, DifferenceKind.CHANGE, DifferenceSource.LEFT);
- } else if (isFeatureMapEntryMove(comparison, (FeatureMap.Entry)diffCandidate,
+ } else if (isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate,
DifferenceSource.LEFT)) {
featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.LEFT);
} else {
@@ -662,7 +662,7 @@ public class DefaultDiffEngine implements IDiffEngine {
if (isFeatureMapEntryKeyChange(equality, (FeatureMap.Entry)diffCandidate, originValues)) {
featureChange(match, feature, diffCandidate, DifferenceKind.CHANGE,
DifferenceSource.RIGHT);
- } else if (isFeatureMapEntryMove(comparison, (FeatureMap.Entry)diffCandidate,
+ } else if (isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate,
DifferenceSource.RIGHT)) {
featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.RIGHT);
} else {
@@ -742,7 +742,7 @@ public class DefaultDiffEngine implements IDiffEngine {
// A value of a FeatureMap changed his key
if (isFeatureMapEntryKeyChange(equality, (FeatureMap.Entry)diffCandidate, rightValues)) {
featureChange(match, feature, diffCandidate, DifferenceKind.CHANGE, DifferenceSource.LEFT);
- } else if (isFeatureMapEntryMove(comparison, (FeatureMap.Entry)diffCandidate,
+ } else if (isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate,
DifferenceSource.LEFT)) {
featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.LEFT);
} else {
@@ -814,7 +814,7 @@ public class DefaultDiffEngine implements IDiffEngine {
private boolean isFeatureMapMove(final Comparison comparison, final EStructuralFeature feature,
final Object diffCandidate, final List<Object> values, final DifferenceSource source) {
return FeatureMapUtil.isFeatureMap(feature)
- && isFeatureMapEntryMove(comparison, (FeatureMap.Entry)diffCandidate, source);
+ && isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate, source);
}
/**
@@ -899,22 +899,25 @@ public class DefaultDiffEngine implements IDiffEngine {
}
/**
- * Checks if the entry has its equivalent in the opposite side, and thus is a DifferenceKind.MOVE
- * difference.
+ * Checks if the entry's value has its equivalent in the opposite side, and thus is a DifferenceKind.MOVE
+ * difference. If the FeatureMapEntry is non-contained the method will return {@code false}.
*
* @param comparison
* The comparison object.
* @param entry
- * The FeatureMap.Entry for which we try to find its equivalent.
+ * The FeatureMap.Entry which contains the value for which we try to find its equivalent.
* @param side
* The given DifferenceSource of the entry.
- * @return true if the entry has its equivalent in the opposite side, false otherwise.
+ * @return {@code true} if the entry's value has its equivalent in the opposite side and is contained
+ * within the feature map, {@code false} otherwise.
*/
- private boolean isFeatureMapEntryMove(final Comparison comparison, FeatureMap.Entry entry,
+ private boolean isFeatureMapValueMove(final Comparison comparison, FeatureMap.Entry entry,
DifferenceSource side) {
final boolean move;
final Object entryValue = entry.getValue();
- if (entryValue instanceof EObject) {
+ final EReference structuralFeature = (EReference)entry.getEStructuralFeature();
+
+ if (entryValue instanceof EObject && structuralFeature.isContainment()) {
final Match candidateMatch = comparison.getMatch((EObject)entryValue);
if (candidateMatch == null) {

Back to the top