diff options
10 files changed, 420 insertions, 21 deletions
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/MatchAccessorTest.java b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/MatchAccessorTest.java new file mode 100644 index 000000000..781e2dd38 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/MatchAccessorTest.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright (c) 2016 Obeo. + * 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 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.tests.contentmergeviewer.accessor.match; + +import static org.eclipse.emf.compare.utils.EMFComparePredicates.addedToReference; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.removedFromReference; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.EMFCompare; +import org.eclipse.emf.compare.EMFCompare.Builder; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.rcp.internal.extension.impl.EMFCompareBuilderConfigurator; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.factory.impl.MatchAccessorFactory; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.MatchAccessor; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.tests.contentmergeviewer.accessor.match.data.MatchAccessorInputData; +import org.eclipse.emf.compare.scope.DefaultComparisonScope; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; +import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterators; + +/** + * Tests for {@link MatchAccessor}. + * + * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a> + */ +@SuppressWarnings("restriction") +public class MatchAccessorTest { + + private final static MatchAccessorInputData inputData = new MatchAccessorInputData(); + + private final static ComposedAdapterFactory fAdapterFactory = new ComposedAdapterFactory( + ComposedAdapterFactory.Descriptor.Registry.INSTANCE); + + private static Comparison comparison; + + @BeforeClass + public static void beforeClass() throws IOException { + fAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory()); + fAdapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory()); + final Resource leftResource = inputData.getLeft(); + final Resource rightResource = inputData.getRight(); + final Resource originResource = inputData.getOrigin(); + + final IComparisonScope scope = new DefaultComparisonScope(leftResource, rightResource, + originResource); + final Builder comparisonBuilder = EMFCompare.builder(); + EMFCompareBuilderConfigurator.createDefault().configure(comparisonBuilder); + comparison = comparisonBuilder.build().compare(scope); + } + + @Test + public void testEClassifiersAdd() { + final List<Diff> differences = comparison.getDifferences(); + + final Predicate<? super Diff> item = addedToReference("extlibrary", "eClassifiers", + "extlibrary.Item"); + final Diff itemDiff = Iterators.find(differences.iterator(), item); + final EObject itemValue = (EObject)MergeViewerUtil.getDiffValue(itemDiff); + final Match itemMatch = comparison.getMatch(itemValue); + + final MatchAccessorFactory factory = new MatchAccessorFactory(); + final ITypedElement leftTypedElement = factory.createLeft(fAdapterFactory, itemMatch); + final ITypedElement rightTypedElement = factory.createRight(fAdapterFactory, itemMatch); + final ITypedElement originTypedElement = factory.createAncestor(fAdapterFactory, itemMatch); + + if (leftTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)leftTypedElement).getDiff(); + assertEquals(diff, itemDiff); + } + if (rightTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)rightTypedElement).getDiff(); + assertEquals(diff, itemDiff); + } + if (originTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)originTypedElement).getDiff(); + assertEquals(diff, itemDiff); + } + } + + @Test + public void testEStructuralFeaturesDelete() { + final List<Diff> differences = comparison.getDifferences(); + + final Predicate<? super Diff> title = removedFromReference("extlibrary.Book", "eStructuralFeatures", + "extlibrary.Book.title"); + final Diff titleDiff = Iterators.find(differences.iterator(), title); + final EObject titleValue = (EObject)MergeViewerUtil.getDiffValue(titleDiff); + final Match titleMatch = comparison.getMatch(titleValue); + + final MatchAccessorFactory factory = new MatchAccessorFactory(); + final ITypedElement leftTypedElement = factory.createLeft(fAdapterFactory, titleMatch); + final ITypedElement rightTypedElement = factory.createRight(fAdapterFactory, titleMatch); + final ITypedElement originTypedElement = factory.createAncestor(fAdapterFactory, titleMatch); + + if (leftTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)leftTypedElement).getDiff(); + assertEquals(diff, titleDiff); + } + if (rightTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)rightTypedElement).getDiff(); + assertEquals(diff, titleDiff); + } + if (originTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)originTypedElement).getDiff(); + assertEquals(diff, titleDiff); + } + } + + @Test + public void testELiteralsMultipleDelete() { + final List<Diff> differences = comparison.getDifferences(); + final MatchAccessorFactory factory = new MatchAccessorFactory(); + + final Predicate<? super Diff> encyclopedia = removedFromReference("extlibrary.BookCategory", + "eLiterals", "extlibrary.BookCategory.Encyclopedia"); + final Diff encyclopediaDiff = Iterators.find(differences.iterator(), encyclopedia); + final EObject encyclopediaValue = (EObject)MergeViewerUtil.getDiffValue(encyclopediaDiff); + final Match encyclopediaMatch = comparison.getMatch(encyclopediaValue); + + final ITypedElement encyclopediaLeftTypedElement = factory.createLeft(fAdapterFactory, + encyclopediaMatch); + final ITypedElement encyclopediaRightTypedElement = factory.createRight(fAdapterFactory, + encyclopediaMatch); + final ITypedElement encyclopediaOriginTypedElement = factory.createAncestor(fAdapterFactory, + encyclopediaMatch); + + if (encyclopediaLeftTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)encyclopediaLeftTypedElement).getDiff(); + assertEquals(diff, encyclopediaDiff); + } + if (encyclopediaRightTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)encyclopediaRightTypedElement).getDiff(); + assertEquals(diff, encyclopediaDiff); + } + if (encyclopediaOriginTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)encyclopediaOriginTypedElement).getDiff(); + assertEquals(diff, encyclopediaDiff); + } + + final Predicate<? super Diff> dictionary = removedFromReference("extlibrary.BookCategory", + "eLiterals", "extlibrary.BookCategory.Dictionary"); + final Diff dictionaryDiff = Iterators.find(differences.iterator(), dictionary); + final EObject dictionaryValue = (EObject)MergeViewerUtil.getDiffValue(dictionaryDiff); + final Match dictionaryMatch = comparison.getMatch(dictionaryValue); + + final ITypedElement dictionaryLeftTypedElement = factory.createLeft(fAdapterFactory, dictionaryMatch); + final ITypedElement dictionaryRightTypedElement = factory.createRight(fAdapterFactory, + dictionaryMatch); + final ITypedElement dictionaryOriginTypedElement = factory.createAncestor(fAdapterFactory, + dictionaryMatch); + + if (dictionaryLeftTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)dictionaryLeftTypedElement).getDiff(); + assertEquals(diff, dictionaryDiff); + } + if (dictionaryRightTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)dictionaryRightTypedElement).getDiff(); + assertEquals(diff, dictionaryDiff); + } + if (dictionaryOriginTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)dictionaryOriginTypedElement).getDiff(); + assertEquals(diff, dictionaryDiff); + } + } + + @Test + public void testEStructuralFeaturesMultipleAdd() { + final List<Diff> differences = comparison.getDifferences(); + final MatchAccessorFactory factory = new MatchAccessorFactory(); + + final Predicate<? super Diff> borrowed = addedToReference("extlibrary.Borrower", + "eStructuralFeatures", "extlibrary.Borrower.borrowed"); + final Diff borrowedDiff = Iterators.find(differences.iterator(), borrowed); + final EObject borrowedValue = (EObject)MergeViewerUtil.getDiffValue(borrowedDiff); + final Match borrowedMatch = comparison.getMatch(borrowedValue); + + final ITypedElement borrowedLeftTypedElement = factory.createLeft(fAdapterFactory, borrowedMatch); + final ITypedElement borrowedRightTypedElement = factory.createRight(fAdapterFactory, borrowedMatch); + final ITypedElement borrowedOriginTypedElement = factory.createAncestor(fAdapterFactory, + borrowedMatch); + + if (borrowedLeftTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)borrowedLeftTypedElement).getDiff(); + assertEquals(diff, borrowedDiff); + } + if (borrowedRightTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)borrowedRightTypedElement).getDiff(); + assertEquals(diff, borrowedDiff); + } + if (borrowedOriginTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)borrowedOriginTypedElement).getDiff(); + assertEquals(diff, borrowedDiff); + } + + final Predicate<? super Diff> containmentBorrowed = addedToReference("extlibrary.Borrower", + "eStructuralFeatures", "extlibrary.Borrower.containmentBorrowed"); + final Diff containmentBorrowedDiff = Iterators.find(differences.iterator(), containmentBorrowed); + final EObject containmentBorrowedValue = (EObject)MergeViewerUtil + .getDiffValue(containmentBorrowedDiff); + final Match containmentBorrowedMatch = comparison.getMatch(containmentBorrowedValue); + + final ITypedElement containmentBorrowedLeftTypedElement = factory.createLeft(fAdapterFactory, + containmentBorrowedMatch); + final ITypedElement containmentBorrowedRightTypedElement = factory.createRight(fAdapterFactory, + containmentBorrowedMatch); + final ITypedElement containmentBorrowedOriginTypedElement = factory.createAncestor(fAdapterFactory, + containmentBorrowedMatch); + + if (containmentBorrowedLeftTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)containmentBorrowedLeftTypedElement).getDiff(); + assertEquals(diff, containmentBorrowedDiff); + } + if (containmentBorrowedRightTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)containmentBorrowedRightTypedElement).getDiff(); + assertEquals(diff, containmentBorrowedDiff); + } + if (containmentBorrowedOriginTypedElement instanceof MergeViewerItem) { + Diff diff = ((MergeViewerItem)containmentBorrowedOriginTypedElement).getDiff(); + assertEquals(diff, containmentBorrowedDiff); + } + } +} diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/MatchAccessorInputData.java b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/MatchAccessorInputData.java new file mode 100644 index 000000000..83415adec --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/MatchAccessorInputData.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2016 Obeo. + * 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 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.tests.contentmergeviewer.accessor.match.data; + +import java.io.IOException; + +import org.eclipse.emf.compare.tests.edit.data.ResourceScopeProvider; +import org.eclipse.emf.compare.tests.framework.AbstractInputData; +import org.eclipse.emf.ecore.resource.Resource; + +public class MatchAccessorInputData extends AbstractInputData implements ResourceScopeProvider { + + public Resource getLeft() throws IOException { + return loadFromClassLoader("left.ecore"); + } + + public Resource getRight() throws IOException { + return loadFromClassLoader("right.ecore"); + } + + public Resource getOrigin() throws IOException { + return loadFromClassLoader("origin.ecore"); + } +} diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/left.ecore b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/left.ecore new file mode 100644 index 000000000..b26859bfa --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/left.ecore @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmi:id="_14sTEG60EeGkd4g88tZXfA" name="extlibrary" nsURI="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0" + nsPrefix="extlib"> + <eClassifiers xsi:type="ecore:EClass" xmi:id="_146VgG60EeGkd4g88tZXfA" name="Book"> + <eStructuralFeatures xsi:type="ecore:EAttribute" xmi:id="_146VgW60EeGkd4g88tZXfA" + name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" xmi:id="_15F7sG60EeGkd4g88tZXfA" name="BookCategory"> + <eLiterals xmi:id="_XID4MG9IEeG7V_vNzpYwOw" name="Encyclopedia" value="3" literal="Encyclopedia"/> + <eLiterals xmi:id="_XIEfQG9IEeG7V_vNzpYwOw" name="Dictionary" value="4"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Borrowable" abstract="true" interface="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Borrower"/> +</ecore:EPackage> diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/origin.ecore b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/origin.ecore new file mode 100644 index 000000000..b26859bfa --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/origin.ecore @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmi:id="_14sTEG60EeGkd4g88tZXfA" name="extlibrary" nsURI="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0" + nsPrefix="extlib"> + <eClassifiers xsi:type="ecore:EClass" xmi:id="_146VgG60EeGkd4g88tZXfA" name="Book"> + <eStructuralFeatures xsi:type="ecore:EAttribute" xmi:id="_146VgW60EeGkd4g88tZXfA" + name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" xmi:id="_15F7sG60EeGkd4g88tZXfA" name="BookCategory"> + <eLiterals xmi:id="_XID4MG9IEeG7V_vNzpYwOw" name="Encyclopedia" value="3" literal="Encyclopedia"/> + <eLiterals xmi:id="_XIEfQG9IEeG7V_vNzpYwOw" name="Dictionary" value="4"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Borrowable" abstract="true" interface="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Borrower"/> +</ecore:EPackage> diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/right.ecore b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/right.ecore new file mode 100644 index 000000000..943f732da --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/contentmergeviewer/accessor/match/data/right.ecore @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmi:id="_14sTEG60EeGkd4g88tZXfA" name="extlibrary" nsURI="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0" + nsPrefix="extlib"> + <eClassifiers xsi:type="ecore:EClass" xmi:id="_146VgG60EeGkd4g88tZXfA" name="Book"/> + <eClassifiers xsi:type="ecore:EEnum" xmi:id="_15F7sG60EeGkd4g88tZXfA" name="BookCategory"/> + <eClassifiers xsi:type="ecore:EClass" name="Item" abstract="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Borrowable" abstract="true" interface="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Borrower"> + <eStructuralFeatures xsi:type="ecore:EReference" name="borrowed" upperBound="-1" + eType="#//Borrowable"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containmentBorrowed" upperBound="-1" + eType="#//Borrowable" containment="true"/> + </eClassifiers> +</ecore:EPackage> diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/suite/AllTests.java index 8b2d0fe64..6ec0dfeaa 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/suite/AllTests.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/suite/AllTests.java @@ -13,6 +13,7 @@ package org.eclipse.emf.compare.rcp.ui.tests.suite; import org.eclipse.emf.compare.ComparePackage; +import org.eclipse.emf.compare.rcp.ui.tests.contentmergeviewer.accessor.match.MatchAccessorTest; import org.eclipse.emf.compare.rcp.ui.tests.match.RCPMatchEngineFactoryRegistryTest; import org.eclipse.emf.compare.rcp.ui.tests.mergeviewer.item.MergeViewerItemFeatureMapsTest; import org.eclipse.emf.compare.rcp.ui.tests.mergeviewer.item.MergeViewerItemPseudoConflictTest; @@ -43,7 +44,7 @@ import junit.textui.TestRunner; MergeViewerItemPseudoConflictTest.class, MergeViewerItemFeatureMapsTest.class, TestBasicDifferenceGroupImpl.class, BugsTestSuite.class, TestFeatureMapDifferencesFilter.class, RCPMatchEngineFactoryRegistryTest.class, ThreeWayComparisonGroupProviderTest.class, - ConflictsGroupTest.class, }) + ConflictsGroupTest.class, MatchAccessorTest.class, }) public class AllTests { /** * Launches the test with the given arguments. diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java index 5110d05d4..562a1b337 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2014 Obeo. + * Copyright (c) 2012, 2016 Obeo. * 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,10 +11,13 @@ package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.factory.impl; import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.Match; import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.MatchAccessor; import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.utils.MatchUtil; +import org.eclipse.emf.ecore.EObject; /** * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for @@ -41,7 +44,8 @@ public class MatchAccessorFactory extends AbstractAccessorFactory { * java.lang.Object) */ public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { - return new MatchAccessor(adapterFactory, (Match)target, MergeViewerSide.LEFT); + return new MatchAccessor(adapterFactory, (Match)target, getContainmentReferenceChange((Match)target), + MergeViewerSide.LEFT); } /** @@ -51,7 +55,8 @@ public class MatchAccessorFactory extends AbstractAccessorFactory { * java.lang.Object) */ public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { - return new MatchAccessor(adapterFactory, (Match)target, MergeViewerSide.RIGHT); + return new MatchAccessor(adapterFactory, (Match)target, getContainmentReferenceChange((Match)target), + MergeViewerSide.RIGHT); } /** @@ -61,7 +66,33 @@ public class MatchAccessorFactory extends AbstractAccessorFactory { * java.lang.Object) */ public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { - return new MatchAccessor(adapterFactory, (Match)target, MergeViewerSide.ANCESTOR); + return new MatchAccessor(adapterFactory, (Match)target, getContainmentReferenceChange((Match)target), + MergeViewerSide.ANCESTOR); } + /** + * Some Matches are related to an object that has been either added or deleted. In these cases, this + * method returns the Diff representing this addition or deletion. In other cases, this method returns + * <code>null</code>. + * + * @param match + * the given Match. + * @return the Diff on the object related to the given Match if it exists, <code>null</code> otherwise. + */ + private Diff getContainmentReferenceChange(Match match) { + final Iterable<Diff> addOrDeleteContainmentDiffs = MatchUtil.findAddOrDeleteContainmentDiffs(match); + if (addOrDeleteContainmentDiffs != null) { + final EObject left = match.getLeft(); + final EObject right = match.getRight(); + final EObject origin = match.getOrigin(); + for (Diff diff : addOrDeleteContainmentDiffs) { + final Object diffValue = MatchUtil.getValue(diff); + if (diffValue != null + && (diffValue.equals(left) || diffValue.equals(right) || diffValue.equals(origin))) { + return diff; + } + } + } + return null; + } } diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java index a3990f153..e5b3c504d 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2015 Obeo. + * Copyright (c) 2012, 2016 Obeo. * 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 @@ -20,6 +20,7 @@ import java.util.Collection; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.Match; import org.eclipse.emf.compare.ResourceAttachmentChange; import org.eclipse.emf.compare.match.impl.NotLoadedFragmentMatch; @@ -46,6 +47,9 @@ public class MatchAccessor extends AbstractTypedElementAdapter implements ICompa /** The match associated with this accessor. */ private final Match fMatch; + /** The diff associated with this accessor. */ + private Diff fDiff; + /** The side of this accessor. */ private final MergeViewerSide fSide; @@ -60,8 +64,25 @@ public class MatchAccessor extends AbstractTypedElementAdapter implements ICompa * the side of this accessor. */ public MatchAccessor(AdapterFactory adapterFactory, Match match, MergeViewerSide side) { + this(adapterFactory, match, null, side); + } + + /** + * Creates a new object wrapping the given <code>eObject</code>. + * + * @param adapterFactory + * the adapter factory used to create the accessor. + * @param match + * the match to associate with this accessor. + * @param diff + * the diff associated with this accessor. + * @param side + * the side of this accessor. + */ + public MatchAccessor(AdapterFactory adapterFactory, Match match, Diff diff, MergeViewerSide side) { super(adapterFactory); fMatch = match; + fDiff = diff; fSide = side; } @@ -130,10 +151,10 @@ public class MatchAccessor extends AbstractTypedElementAdapter implements ICompa public IMergeViewerItem getInitialItem() { final MergeViewerItem.Container container; if (fMatch instanceof NotLoadedFragmentMatch) { - container = new MergeViewerItem.Container(fMatch.getComparison(), null, fMatch, fMatch, fMatch, + container = new MergeViewerItem.Container(fMatch.getComparison(), fDiff, fMatch, fMatch, fMatch, fSide, getRootAdapterFactory()); } else { - container = new MergeViewerItem.Container(fMatch.getComparison(), null, fMatch, fSide, + container = new MergeViewerItem.Container(fMatch.getComparison(), fDiff, fMatch, fSide, getRootAdapterFactory()); } return container; diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java index fe4d421de..c40ea814b 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java @@ -24,13 +24,11 @@ import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; - -import java.util.Iterator; +import com.google.common.collect.UnmodifiableIterator; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.DifferenceSource; import org.eclipse.emf.compare.Match; -import org.eclipse.emf.compare.ReferenceChange; import org.eclipse.emf.compare.ResourceAttachmentChange; import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.AbstractDifferenceFilter; import org.eclipse.emf.compare.utils.MatchUtil; @@ -94,7 +92,7 @@ public class CascadingDifferencesFilter extends AbstractDifferenceFilter { // The ancestor has been added/deleted, we must filter the current diff // _unless_ it is refined by the diff that represents the grand-parent // add/delete - ReferenceChange addOrDeleteDiff = findAddOrDeleteDiff(grandParentMatch, side); + Diff addOrDeleteDiff = findAddOrDeleteDiff(grandParentMatch, side); if (addOrDeleteDiff != null) { if (diff.getRefinedBy().contains(addOrDeleteDiff)) { // recurse @@ -107,14 +105,14 @@ public class CascadingDifferencesFilter extends AbstractDifferenceFilter { return ret; } - private ReferenceChange findAddOrDeleteDiff(Match match, DifferenceSource side) { - EObject container = match.eContainer(); - if (container instanceof Match) { - @SuppressWarnings("unchecked") - Iterator<Diff> candidates = Iterators.filter(((Match)container).getDifferences().iterator(), - and(fromSide(side), CONTAINMENT_REFERENCE_CHANGE, ofKind(ADD, DELETE))); - if (candidates.hasNext()) { - return (ReferenceChange)candidates.next(); + private Diff findAddOrDeleteDiff(Match match, DifferenceSource side) { + final Iterable<Diff> addOrDeleteContainmentDiffs = MatchUtil + .findAddOrDeleteContainmentDiffs(match); + if (addOrDeleteContainmentDiffs != null) { + final UnmodifiableIterator<Diff> sideChanges = Iterators + .filter(addOrDeleteContainmentDiffs.iterator(), fromSide(side)); + if (sideChanges.hasNext()) { + return sideChanges.next(); } } return null; diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/MatchUtil.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/MatchUtil.java index 6dffad702..c50133d1c 100644 --- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/MatchUtil.java +++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/MatchUtil.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 @@ -11,8 +11,15 @@ *******************************************************************************/ package org.eclipse.emf.compare.utils; +import static com.google.common.base.Predicates.and; +import static org.eclipse.emf.compare.DifferenceKind.ADD; +import static org.eclipse.emf.compare.DifferenceKind.DELETE; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.CONTAINMENT_REFERENCE_CHANGE; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind; import static org.eclipse.emf.compare.utils.ReferenceUtil.getAsList; +import com.google.common.collect.Iterables; + import org.eclipse.emf.common.util.URI; import org.eclipse.emf.compare.AttributeChange; import org.eclipse.emf.compare.Comparison; @@ -290,4 +297,22 @@ public final class MatchUtil { } } + /** + * Get the potential ReferenceChanges that represent add/delete containment differences in the parent + * Match of the given Match. + * + * @param match + * the given Match. + * @return the potential ReferenceChanges that represent add/delete containment differences in the parent + * Match of the given Match, <code>null</code> otherwise. + */ + public static Iterable<Diff> findAddOrDeleteContainmentDiffs(Match match) { + final EObject container = match.eContainer(); + if (container instanceof Match) { + return Iterables.filter(((Match)container).getDifferences(), + and(CONTAINMENT_REFERENCE_CHANGE, ofKind(ADD, DELETE))); + } + return null; + } + } |