/* * Copyright (c) 2012, 2013, 2016 Eike Stepper (Berlin, Germany) 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: * Eike Stepper - initial API and implementation */ package org.eclipse.emf.cdo.tests; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.compare.CDOCompare; import org.eclipse.emf.cdo.compare.CDOCompareUtil; import org.eclipse.emf.cdo.compare.CDOComparisonScope; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.tests.config.IRepositoryConfig; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires; import org.eclipse.emf.cdo.tests.model1.Category; import org.eclipse.emf.cdo.tests.model1.Company; import org.eclipse.emf.cdo.tests.model1.Product1; import org.eclipse.emf.cdo.tests.model1.legacy.Model1Factory; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.compare.Comparison; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.EMFCompare; import org.eclipse.emf.compare.Match; import org.eclipse.emf.compare.diff.DefaultDiffEngine; import org.eclipse.emf.compare.diff.DiffBuilder; import org.eclipse.emf.compare.diff.FeatureFilter; import org.eclipse.emf.compare.diff.IDiffEngine; import org.eclipse.emf.compare.scope.DefaultComparisonScope; import org.eclipse.emf.compare.scope.IComparisonScope; import org.eclipse.emf.ecore.EAttribute; 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.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; import java.util.Collections; import java.util.Set; /** * @author Eike Stepper */ @Requires(IRepositoryConfig.CAPABILITY_AUDITING) public class EMFCompareTest extends AbstractCDOTest { public void testAllContentsOfCompany() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource = transaction.createResource(getResourcePath("/res1")); Company company = createCompany(); company.setName("ESC"); resource.getContents().add(company); resource.getContents().add(createCompany()); resource.getContents().add(createCompany()); transaction.commit(); company.setName("Sympedia"); CDOCommitInfo commit2 = transaction.commit(); company.setName("Eclipse"); transaction.commit(); Comparison comparison = CDOCompareUtil.compare(CDOUtil.getCDOObject(company), session.openView(commit2), null); dump(comparison); } public void testAllContentsOfRoot() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource = transaction.createResource(getResourcePath("/res1")); Company company = createCompany(); company.setName("ESC"); resource.getContents().add(company); resource.getContents().add(createCompany()); resource.getContents().add(createCompany()); transaction.commit(); company.setName("Sympedia"); CDOCommitInfo commit2 = transaction.commit(); company.setName("Eclipse"); transaction.commit(); Comparison comparison = CDOCompareUtil.compare(CDOUtil.getCDOObject(transaction.getRootResource()), session.openView(commit2), null); dump(comparison); } public void testMinimal() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource = transaction.createResource(getResourcePath("/res1")); Company company = createCompany(); resource.getContents().add(company); resource.getContents().add(createCompany()); resource.getContents().add(createCompany()); transaction.commit(); company.setName("Sympedia"); CDOCommitInfo commit2 = transaction.commit(); company.setName("Eclipse"); transaction.commit(); Comparison comparison = CDOCompareUtil.compare(transaction, session.openView(commit2), null); dump(comparison); } public void testContainmentProxy() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource1 = transaction.createResource(getResourcePath("/res1")); CDOResource resource2 = transaction.createResource(getResourcePath("/res2")); Company company = getModel1Factory().createCompany(); company.setName("Eclipse"); resource1.getContents().add(company); Category categoryCrossContained = getModel1Factory().createCategory(); categoryCrossContained.setName("Category"); company.getCategories().add(categoryCrossContained); resource2.getContents().add(categoryCrossContained); for (int i = 0; i < 10; ++i) { Product1 product = getModel1Factory().createProduct1(); categoryCrossContained.getProducts().add(product); } CDOCommitInfo commitInfo = transaction.commit(); Product1 product0 = categoryCrossContained.getProducts().get(0); product0.setName("CHANGED"); transaction.commit(); Comparison comparison = CDOCompareUtil.compare(transaction, session.openView(commitInfo), null); dump(comparison); assertEquals(0, comparison.getMatch(categoryCrossContained).getDifferences().size()); } public void testContainmentProxyEMF() throws Exception { ResourceSet resourceSetA = createResourceSet(); Category categoryCrossContained = populate(resourceSetA); ResourceSet resourceSetB = createResourceSet(); Product1 product0 = populate(resourceSetB).getProducts().get(0); product0.setName("ProductB"); IComparisonScope scope = new DefaultComparisonScope(resourceSetA, resourceSetB, null); // Configure EMF Compare // IEObjectMatcher matcher = DefaultMatchEngine.createDefaultEObjectMatcher(UseIdentifiers.NEVER); // IComparisonFactory comparisonFactory = new DefaultComparisonFactory(new DefaultEqualityHelperFactory()); // IMatchEngine matchEngine = new DefaultMatchEngine(matcher, comparisonFactory); // EMFCompare comparator = EMFCompare.builder().setMatchEngine(matchEngine).build(); EMFCompare comparator = EMFCompare.builder().build(); // Compare the two models Comparison comparison = comparator.compare(scope); dump(comparison); assertEquals(0, comparison.getMatch(categoryCrossContained).getDifferences().size()); assertEquals(1, comparison.getMatch(product0).getDifferences().size()); } public void testNoContainmentProxy() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource1 = transaction.createResource(getResourcePath("/res1")); Company company = getModel1Factory().createCompany(); company.setName("Company"); resource1.getContents().add(company); Category category = getModel1Factory().createCategory(); category.setName("Category"); company.getCategories().add(category); for (int i = 0; i < 10; ++i) { Product1 product = getModel1Factory().createProduct1(); category.getProducts().add(product); } company.setName("Company2"); CDOCommitInfo commitInfo = transaction.commit(); category.getProducts().get(0).setName("EclipseProduct"); transaction.commit(); Comparison comparison = CDOCompareUtil.compare(transaction, session.openView(commitInfo), null); dump(comparison); assertEquals(0, comparison.getMatch(category).getDifferences().size()); } public void testChanges() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource = transaction.createResource(getResourcePath("/res1")); Company company = getModel1Factory().createCompany(); company.setName("Company"); resource.getContents().add(company); Category category1 = getModel1Factory().createCategory(); category1.setName("Category1"); company.getCategories().add(category1); transaction.commit(); // Change category1 category1.setName("CHANGED"); Category category2 = getModel1Factory().createCategory(); category2.setName("Category2"); // Change company, add category2 company.getCategories().add(category2); Comparison comparison = CDOCompareUtil.compareUncommittedChanges(transaction); dump(comparison); assertEquals(1, comparison.getMatch(category1).getDifferences().size()); assertEquals(1, comparison.getMatch(company).getDifferences().size()); } public void testChangesDelete() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource = transaction.createResource(getResourcePath("/res1")); Company company = getModel1Factory().createCompany(); company.setName("Company"); resource.getContents().add(company); Category category = getModel1Factory().createCategory(); category.setName("Category"); company.getCategories().add(category); transaction.commit(); company.getCategories().clear(); Comparison comparison = CDOCompareUtil.compareUncommittedChanges(transaction); dump(comparison); assertEquals(1, comparison.getMatch(company).getDifferences().size()); } public void testFeatureFilter() throws Exception { CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource resource = transaction.createResource(getResourcePath("/res1")); Company company = createCompany(); company.setName("ESC"); company.setCity("Berlin"); resource.getContents().add(company); CDOCommitInfo commit1 = transaction.commit(); company.setName("Eclipse"); company.setCity("Ottawa"); transaction.commit(); IComparisonScope scope = CDOComparisonScope.Minimal.create(transaction, session.openView(commit1), null); Comparison comparison = new CDOCompare() { @Override protected IDiffEngine createDiffEngine() { return new DefaultDiffEngine(new DiffBuilder()) { @Override protected FeatureFilter createFeatureFilter() { return new FeatureFilter() { Set<? extends EStructuralFeature> ignored = Collections.singleton(getModel1Package().getAddress_City()); @Override protected boolean isIgnoredAttribute(EAttribute attribute) { return ignored.contains(attribute); } }; } }; } }.compare(scope); dump(comparison); assertEquals(1, comparison.getMatch(company).getDifferences().size()); } private Company createCompany() { Company company = getModel1Factory().createCompany(); company.getCategories().add(getModel1Factory().createCategory()); company.getCategories().add(getModel1Factory().createCategory()); company.getCategories().add(getModel1Factory().createCategory()); company.getCategories().add(getModel1Factory().createCategory()); company.getCategories().add(getModel1Factory().createCategory()); return company; } private static ResourceSet createResourceSet() { ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl()); return resourceSet; } private static Category populate(ResourceSet resourceSet) { Model1Factory factory = org.eclipse.emf.cdo.tests.model1.legacy.Model1Factory.eINSTANCE; Resource resourceA1 = resourceSet.createResource(URI.createURI("res1")); Resource resourceA2 = resourceSet.createResource(URI.createURI("res2")); Company company = factory.createCompany(); company.setName("Eclipse"); resourceA1.getContents().add(company); Category categoryCrossContained = factory.createCategory(); categoryCrossContained.setName("Category"); company.getCategories().add(categoryCrossContained); resourceA2.getContents().add(categoryCrossContained); for (int i = 0; i < 10; ++i) { Product1 product = factory.createProduct1(); product.setName("Product" + i); categoryCrossContained.getProducts().add(product); } return categoryCrossContained; } private static void dump(Comparison comparison) { dump(comparison.getMatches(), ""); } private static void dump(EList<Match> matches, String indent) { for (Match match : matches) { System.out.println(indent + "Match:"); System.out.println(indent + " Left: " + toString(match == null ? null : match.getLeft())); System.out.println(indent + " Right: " + toString(match == null ? null : match.getRight())); String origin = toString(match.getOrigin()); if (origin != null) { System.out.println(indent + " Origin: " + origin); } System.out.println(indent + " Differences:"); for (Diff diff : match.getDifferences()) { System.out.println(indent + " " + diff); } dump(match.getSubmatches(), indent + " "); } } private static String toString(EObject object) { if (object == null) { return null; } CDOObject cdoObject = CDOUtil.getCDOObject(object); if (cdoObject != null) { CDORevision revision = cdoObject.cdoRevision(); if (revision != null) { return revision.toString(); } } return object.toString(); } }