diff options
author | Mathieu Cartaud | 2016-04-27 07:48:45 +0000 |
---|---|---|
committer | Mathieu Cartaud | 2016-04-27 15:01:22 +0000 |
commit | 851f823d7d66c3d6bcd22f88430e9db4da94a3a1 (patch) | |
tree | a50309a414566c46244839cd524e49364d1b3d9e /plugins | |
parent | 31aa7916d75a14e46f074bfc3d8dfbd303502b27 (diff) | |
download | org.eclipse.emf.compare-851f823d7d66c3d6bcd22f88430e9db4da94a3a1.tar.gz org.eclipse.emf.compare-851f823d7d66c3d6bcd22f88430e9db4da94a3a1.tar.xz org.eclipse.emf.compare-851f823d7d66c3d6bcd22f88430e9db4da94a3a1.zip |
Bug: 492341
Change-Id: I44c972aa1aff0d093f9aa5d2a7c7e2967187ce68
Signed-off-by: Mathieu Cartaud <mathieu.cartaud@obeo.fr>
Diffstat (limited to 'plugins')
15 files changed, 276 insertions, 21 deletions
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 index 518cccf07..c16a8d20f 100644 --- 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 @@ -1,5 +1,5 @@ <?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"> +<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" xmi:id="_root"> <containmentRef1 xsi:type="nodes:NodeFeatureMapNonContainment" name="n" xmi:id="_n"> <firstKeyNC href="#_q"/> </containmentRef1> 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 index 9002ad053..f673ff9d2 100644 --- 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 @@ -1,5 +1,5 @@ <?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"> +<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" xmi:id="_root"> <containmentRef1 xsi:type="nodes:NodeFeatureMapNonContainment" name="n" xmi:id="_n"> </containmentRef1> <containmentRef1 xsi:type="nodes:Node" name="r" xmi:id="_r"> diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/ReqComputingTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/ReqComputingTest.java index 787378115..a316870b0 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/ReqComputingTest.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/ReqComputingTest.java @@ -23,9 +23,12 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; import com.google.common.collect.Iterators; import java.io.IOException; +import java.util.Collection; import java.util.List; import org.eclipse.emf.common.util.EList; @@ -33,10 +36,13 @@ import org.eclipse.emf.compare.Comparison; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.EMFCompare; import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.ResourceAttachmentChange; import org.eclipse.emf.compare.scope.DefaultComparisonScope; import org.eclipse.emf.compare.scope.IComparisonScope; import org.eclipse.emf.compare.tests.req.data.ReqInputData; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.junit.Test; @SuppressWarnings("nls") @@ -648,6 +654,111 @@ public class ReqComputingTest { assertTrue(singleChange.getRequires().contains(added2)); } + @Test + public void testH1UseCase() throws IOException { + final Resource left = input.getH1Left(); + final Resource origin = input.getH1Ancestor(); + final Resource right = input.getH1Right(); + + final ResourceSet leftSet = left.getResourceSet(); + final ResourceSet originSet = origin.getResourceSet(); + final ResourceSet rightSet = right.getResourceSet(); + + assertNotNull(leftSet); + assertNotNull(originSet); + assertNotNull(rightSet); + + EcoreUtil.resolveAll(leftSet); + EcoreUtil.resolveAll(originSet); + EcoreUtil.resolveAll(rightSet); + + assertEquals(1, leftSet.getResources().size()); + assertEquals(2, originSet.getResources().size()); + assertEquals(2, rightSet.getResources().size()); + + IComparisonScope scope = new DefaultComparisonScope(leftSet, rightSet, originSet); + Comparison comparison = EMFCompare.builder().build().compare(scope); + testH(TestKind.DELETE, comparison); + + scope = new DefaultComparisonScope(rightSet, leftSet, originSet); + comparison = EMFCompare.builder().build().compare(scope); + testH(TestKind.DELETE, comparison); + } + + @Test + public void testH2UseCase() throws IOException { + final Resource left = input.getH2Left(); + final Resource origin = input.getH2Ancestor(); + final Resource right = input.getH2Right(); + + final ResourceSet leftSet = left.getResourceSet(); + final ResourceSet originSet = origin.getResourceSet(); + final ResourceSet rightSet = right.getResourceSet(); + + assertNotNull(leftSet); + assertNotNull(originSet); + assertNotNull(rightSet); + + EcoreUtil.resolveAll(leftSet); + EcoreUtil.resolveAll(originSet); + EcoreUtil.resolveAll(rightSet); + + assertEquals(2, leftSet.getResources().size()); + assertEquals(1, originSet.getResources().size()); + assertEquals(1, rightSet.getResources().size()); + + IComparisonScope scope = new DefaultComparisonScope(leftSet, rightSet, originSet); + Comparison comparison = EMFCompare.builder().build().compare(scope); + testH(TestKind.ADD, comparison); + + scope = new DefaultComparisonScope(rightSet, leftSet, originSet); + comparison = EMFCompare.builder().build().compare(scope); + testH(TestKind.ADD, comparison); + } + + private void testH(TestKind testKind, Comparison comparison) { + + EList<Diff> differences = comparison.getDifferences(); + Collection<Diff> racs = Collections2.filter(differences, Predicates + .instanceOf(ResourceAttachmentChange.class)); + assertEquals(1, racs.size()); + Diff rac = racs.iterator().next(); + + Predicate<? super Diff> deleteFragmentedDiffDescription = null; + Predicate<? super Diff> deleteInnerNodeDiffDescription = null; + + if (testKind == TestKind.DELETE) { + deleteFragmentedDiffDescription = removed("root.fragmented"); //$NON-NLS-1$ + deleteInnerNodeDiffDescription = removed("root.fragmented.innerNode"); //$NON-NLS-1$ + } else { + deleteFragmentedDiffDescription = added("root.fragmented"); //$NON-NLS-1$ + deleteInnerNodeDiffDescription = added("root.fragmented.innerNode"); //$NON-NLS-1$ + } + + final Diff deleteFragmentedDiff = Iterators.find(differences.iterator(), + deleteFragmentedDiffDescription); + final Diff deleteInnerNodeDiff = Iterators.find(differences.iterator(), + deleteInnerNodeDiffDescription); + + if (testKind == TestKind.DELETE) { + assertEquals(1, rac.getRequiredBy().size()); + assertEquals(deleteFragmentedDiff, rac.getRequiredBy().get(0)); + assertEquals(0, rac.getRequires().size()); + + assertEquals(1, deleteInnerNodeDiff.getRequiredBy().size()); + assertEquals(deleteFragmentedDiff, deleteInnerNodeDiff.getRequiredBy().get(0)); + assertEquals(0, deleteInnerNodeDiff.getRequires().size()); + } else { + assertEquals(1, rac.getRequires().size()); + assertEquals(deleteFragmentedDiff, rac.getRequires().get(0)); + assertEquals(0, rac.getRequiredBy().size()); + + assertEquals(1, deleteInnerNodeDiff.getRequires().size()); + assertEquals(deleteFragmentedDiff, deleteInnerNodeDiff.getRequires().get(0)); + assertEquals(0, deleteInnerNodeDiff.getRequiredBy().size()); + } + } + private void testAB1(TestKind kind, final Comparison comparison) { final List<Diff> differences = comparison.getDifferences(); diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/ReqInputData.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/ReqInputData.java index eff074820..90d1348d7 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/ReqInputData.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/ReqInputData.java @@ -14,6 +14,7 @@ import java.io.IOException; import org.eclipse.emf.compare.tests.framework.AbstractInputData; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; public class ReqInputData extends AbstractInputData { public Resource getA1Left() throws IOException { @@ -415,4 +416,28 @@ public class ReqInputData extends AbstractInputData { public Resource getG1Right() throws IOException { return loadFromClassLoader("g1/right.nodes"); //$NON-NLS-1$ } + + public Resource getH1Left() throws IOException { + return loadFromClassLoader("h1/left/origin.nodes", new ResourceSetImpl()); //$NON-NLS-1$ + } + + public Resource getH1Right() throws IOException { + return loadFromClassLoader("h1/right/origin.nodes", new ResourceSetImpl()); //$NON-NLS-1$ + } + + public Resource getH1Ancestor() throws IOException { + return loadFromClassLoader("h1/ancestor/origin.nodes", new ResourceSetImpl()); //$NON-NLS-1$ + } + + public Resource getH2Left() throws IOException { + return loadFromClassLoader("h2/left/origin.nodes", new ResourceSetImpl()); //$NON-NLS-1$ + } + + public Resource getH2Right() throws IOException { + return loadFromClassLoader("h2/right/origin.nodes", new ResourceSetImpl()); //$NON-NLS-1$ + } + + public Resource getH2Ancestor() throws IOException { + return loadFromClassLoader("h2/ancestor/origin.nodes", new ResourceSetImpl()); //$NON-NLS-1$ + } } diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/ancestor/fragment.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/ancestor/fragment.nodes new file mode 100644 index 000000000..0eba84fee --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/ancestor/fragment.nodes @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" xmi:id="_QE6YYAcQEeKTxJtDIb3mMw" name="fragmented">
+ <containmentRef1 xmi:id="_gUHAUArkEeaHsdquODvaLA" name="innerNode"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/ancestor/origin.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/ancestor/origin.nodes new file mode 100644 index 000000000..7192229e8 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/ancestor/origin.nodes @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes"
+ xmi:id="_ORexoLlNEeGmS9ESxeCLvg"
+ name="root">
+ <containmentRef1
+ href="fragment.nodes#_QE6YYAcQEeKTxJtDIb3mMw"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/left/origin.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/left/origin.nodes new file mode 100644 index 000000000..6d8762bae --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/left/origin.nodes @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes"
+ xmi:id="_ORexoLlNEeGmS9ESxeCLvg"
+ name="root"/>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/right/fragment.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/right/fragment.nodes new file mode 100644 index 000000000..0eba84fee --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/right/fragment.nodes @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" xmi:id="_QE6YYAcQEeKTxJtDIb3mMw" name="fragmented">
+ <containmentRef1 xmi:id="_gUHAUArkEeaHsdquODvaLA" name="innerNode"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/right/origin.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/right/origin.nodes new file mode 100644 index 000000000..b75ab1666 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h1/right/origin.nodes @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" xmi:id="_ORexoLlNEeGmS9ESxeCLvg" name="root">
+ <containmentRef1 href="fragment.nodes#_QE6YYAcQEeKTxJtDIb3mMw"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/ancestor/origin.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/ancestor/origin.nodes new file mode 100644 index 000000000..6d8762bae --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/ancestor/origin.nodes @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes"
+ xmi:id="_ORexoLlNEeGmS9ESxeCLvg"
+ name="root"/>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/left/fragment.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/left/fragment.nodes new file mode 100644 index 000000000..0eba84fee --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/left/fragment.nodes @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes" xmi:id="_QE6YYAcQEeKTxJtDIb3mMw" name="fragmented">
+ <containmentRef1 xmi:id="_gUHAUArkEeaHsdquODvaLA" name="innerNode"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/left/origin.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/left/origin.nodes new file mode 100644 index 000000000..7192229e8 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/left/origin.nodes @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes"
+ xmi:id="_ORexoLlNEeGmS9ESxeCLvg"
+ name="root">
+ <containmentRef1
+ href="fragment.nodes#_QE6YYAcQEeKTxJtDIb3mMw"/>
+</nodes:Node>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/right/origin.nodes b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/right/origin.nodes new file mode 100644 index 000000000..6d8762bae --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/h2/right/origin.nodes @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<nodes:Node
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:nodes="http://www.eclipse.org/emf/compare/tests/nodes"
+ xmi:id="_ORexoLlNEeGmS9ESxeCLvg"
+ name="root"/>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/useCases b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/useCases index 1c2a52035..e1c970d46 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/useCases +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/req/data/useCases @@ -33,4 +33,8 @@ d - many business model object dependency - right changes e - 3-way tests - left changes
-f - 3 way tests - right changes
\ No newline at end of file +f - 3 way tests - right changes
+
+h - resource attachment change tests
+ h1 - resource attachment change on a deleted object
+ h2 - resource attachment change on a added object
\ No newline at end of file diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/req/DefaultReqEngine.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/req/DefaultReqEngine.java index fe48fc87f..a01e6d611 100644 --- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/req/DefaultReqEngine.java +++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/req/DefaultReqEngine.java @@ -15,6 +15,10 @@ import static com.google.common.base.Predicates.and; import static com.google.common.base.Predicates.instanceOf; import static com.google.common.base.Predicates.or; import static com.google.common.collect.Iterables.filter; +import static org.eclipse.emf.compare.DifferenceKind.ADD; +import static org.eclipse.emf.compare.DifferenceKind.CHANGE; +import static org.eclipse.emf.compare.DifferenceKind.DELETE; +import static org.eclipse.emf.compare.DifferenceKind.MOVE; import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.isAddOrSetDiff; import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.isDeleteOrUnsetDiff; import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.isFeatureMapContainment; @@ -28,6 +32,7 @@ import java.util.List; import java.util.Set; import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.Monitor; import org.eclipse.emf.compare.Comparison; import org.eclipse.emf.compare.ComparisonCanceledException; @@ -105,12 +110,15 @@ public class DefaultReqEngine implements IReqEngine { boolean isAddition = isAddOrSetDiff(difference); boolean isDeletion = !isAddition && isDeleteOrUnsetDiff(difference); - // ADD object - if (isAddition && isReferenceContainment(difference)) { + if (isAddition && isDeleteOrAddResourceAttachmentChange(comparison, difference)) { + requiredDifferences.addAll(getDiffsThatShouldDependOn((ResourceAttachmentChange)difference)); + // ADD object + } else if (isAddition && isReferenceContainment(difference)) { + // if (isAddition && isReferenceContainment(difference)) { // -> requires ADD on the container of the object requiredDifferences.addAll(getDifferenceOnGivenObject(comparison, value.eContainer(), - difference.getSource(), DifferenceKind.ADD)); + difference.getSource(), ADD)); // -> requires DELETE of the origin value on the same containment mono-valued reference requiredDifferences.addAll(getDELOriginValueOnContainmentRefSingle(comparison, difference)); @@ -120,24 +128,27 @@ public class DefaultReqEngine implements IReqEngine { // -> requires ADD of the value of the reference (target object) requiredDifferences.addAll(getDifferenceOnGivenObject(comparison, value, difference - .getSource(), DifferenceKind.ADD)); + .getSource(), ADD)); // -> requires ADD of the object containing the reference final EObject container = MatchUtil.getContainer(comparison, difference); if (container != null) { requiredDifferences.addAll(getDifferenceOnGivenObject(comparison, container, difference - .getSource(), DifferenceKind.ADD)); + .getSource(), ADD)); } requiredDifferences.addAll(Collections2.filter(match.getDifferences(), and( - instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.ADD)))); + instanceOf(ResourceAttachmentChange.class), ofKind(ADD)))); + } else if (isDeletion && isDeleteOrAddResourceAttachmentChange(comparison, difference)) { + requiredByDifferences + .addAll(getDiffsThatShouldDependOn((ResourceAttachmentChange)difference)); // DELETE object } else if (isDeletion && isReferenceContainment(difference)) { // -> requires DELETE of the outgoing references and contained objects requiredDifferences.addAll(getDELOutgoingReferences(comparison, difference)); requiredDifferences.addAll(getDifferenceOnGivenObject(comparison, value.eContents(), - difference.getSource(), DifferenceKind.DELETE)); + difference.getSource(), DELETE)); // -> requires MOVE of contained objects requiredDifferences.addAll(getMOVEContainedObjects(comparison, difference)); @@ -150,33 +161,32 @@ public class DefaultReqEngine implements IReqEngine { // -> is required by DELETE of the target object requiredByDifferences.addAll(getDifferenceOnGivenObject(comparison, value, difference - .getSource(), DifferenceKind.DELETE)); + .getSource(), DELETE)); // MOVE object - } else if (kind == DifferenceKind.MOVE && isReferenceContainment(difference)) { + } else if (kind == MOVE && isReferenceContainment(difference)) { EObject container = value.eContainer(); // -> requires ADD on the container of the object requiredDifferences.addAll(getDifferenceOnGivenObject(comparison, container, difference - .getSource(), DifferenceKind.ADD)); + .getSource(), ADD)); // -> requires MOVE of the container of the object requiredDifferences.addAll(getDifferenceOnGivenObject(comparison, container, difference - .getSource(), DifferenceKind.MOVE)); + .getSource(), MOVE)); // CHANGE reference - } else if (kind == DifferenceKind.CHANGE && !isAddition && !isDeletion + } else if (kind == CHANGE && !isAddition && !isDeletion && !(difference instanceof FeatureMapChange)) { // -> is required by DELETE of the origin target object requiredByDifferences.addAll(getDifferenceOnGivenObject(comparison, MatchUtil.getOriginValue( - comparison, (ReferenceChange)difference), difference.getSource(), - DifferenceKind.DELETE)); + comparison, (ReferenceChange)difference), difference.getSource(), DELETE)); // -> requires ADD of the value of the reference (target object) if required requiredDifferences.addAll(getDifferenceOnGivenObject(comparison, value, difference - .getSource(), DifferenceKind.ADD)); + .getSource(), ADD)); } difference.getRequires().addAll( @@ -190,6 +200,54 @@ public class DefaultReqEngine implements IReqEngine { } /** + * Checks whether the given diff corresponds to a reference change associated with the addition or the + * deletion of an object. + * + * @param comparison + * The comparison + * @param diff + * The diff to consider + * @return <code>true</code> if the given {@code diff} is to be considered a ResourceAttachmentChange with + * ADD or DELETE dependencies, <code>false</code> otherwise. + */ + private boolean isDeleteOrAddResourceAttachmentChange(Comparison comparison, Diff diff) { + if (diff instanceof ResourceAttachmentChange && (diff.getKind() == ADD || diff.getKind() == DELETE)) { + EObject container = MatchUtil.getContainer(comparison, diff); + if (container != null) { + EList<Diff> differences = comparison.getDifferences(container); + for (Diff containedDiff : differences) { + if (containedDiff instanceof ReferenceChange + && ((ReferenceChange)containedDiff).getReference().isContainment() + && containedDiff.getKind() == diff.getKind()) { + return true; + } + } + } + } + return false; + } + + /** + * Compute the dependencies specific to ResourceAttachmentChanges DELETE or ADD. (The addition or deletion + * of the package controlled/uncontrolled must be a dependency of the RAC) + * + * @param diff + * The given difference + * @return a list of dependencies + */ + private Set<ReferenceChange> getDiffsThatShouldDependOn(ResourceAttachmentChange diff) { + Set<ReferenceChange> result = new LinkedHashSet<ReferenceChange>(); + Comparison comparison = diff.getMatch().getComparison(); + EObject container = MatchUtil.getContainer(comparison, diff); + for (ReferenceChange rc : filter(comparison.getDifferences(container), ReferenceChange.class)) { + if (diff.getSource() == rc.getSource() && diff.getKind() == rc.getKind()) { + result.add(rc); + } + } + return result; + } + + /** * From a <code>sourceDifference</code> (ADD) on a containment mono-valued reference, it retrieves a * potential DELETE difference on the origin value. * @@ -211,7 +269,7 @@ public class DefaultReqEngine implements IReqEngine { Object originValue = ReferenceUtil.safeEGet(originContainer, reference); if (originValue instanceof EObject) { result = getDifferenceOnGivenObject(comparison, (EObject)originValue, sourceDifference - .getSource(), DifferenceKind.DELETE); + .getSource(), DELETE); } } } @@ -319,7 +377,7 @@ public class DefaultReqEngine implements IReqEngine { for (Diff candidate : filter(valueMatch.getDifferences(), or( instanceOf(ReferenceChange.class), instanceOf(FeatureMapChange.class)))) { if (candidate.getSource() == sourceDifference.getSource() - && (candidate.getKind() == DifferenceKind.DELETE || isDeleteOrUnsetDiff(candidate))) { + && (candidate.getKind() == DELETE || isDeleteOrUnsetDiff(candidate))) { result.add(candidate); } } @@ -351,7 +409,7 @@ public class DefaultReqEngine implements IReqEngine { ReferenceChange.class)) { if (difference.getReference().isContainment() && difference.getSource() == sourceDifference.getSource() - && difference.getKind() == DifferenceKind.MOVE) { + && difference.getKind() == MOVE) { result.add(difference); } |