| /******************************************************************************* |
| * Copyright (c) 2013, 2015 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.papyrus.compare.diagram.tests; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| |
| import com.google.common.base.Predicate; |
| import com.google.common.collect.Collections2; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.ImmutableSet.Builder; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Iterators; |
| |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.regex.Pattern; |
| |
| 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.ReferenceChange; |
| import org.eclipse.emf.compare.diagram.internal.CompareDiagramPostProcessor; |
| import org.eclipse.emf.compare.diagram.internal.extensions.DiagramDiff; |
| import org.eclipse.emf.compare.diagram.internal.merge.CompareDiagramMerger; |
| import org.eclipse.emf.compare.merge.IMerger; |
| import org.eclipse.emf.compare.postprocessor.PostProcessorDescriptorRegistryImpl; |
| import org.eclipse.emf.compare.scope.DefaultComparisonScope; |
| import org.eclipse.emf.compare.scope.IComparisonScope2; |
| import org.eclipse.emf.compare.tests.postprocess.data.TestPostProcessor; |
| import org.eclipse.emf.compare.uml2.internal.UMLDiff; |
| import org.eclipse.emf.compare.uml2.internal.merge.UMLMerger; |
| import org.eclipse.emf.compare.uml2.internal.postprocessor.UMLPostProcessor; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.gmf.runtime.notation.View; |
| import org.eclipse.uml2.uml.NamedElement; |
| import org.junit.After; |
| import org.junit.Before; |
| |
| @SuppressWarnings("nls") |
| public abstract class AbstractTest { |
| |
| private EMFCompare emfCompare; |
| |
| private PostProcessorDescriptorRegistryImpl<String> postProcessorRegistry; |
| |
| private IMerger.Registry mergerRegistry; |
| |
| @Before |
| public void before() { |
| postProcessorRegistry = new PostProcessorDescriptorRegistryImpl<String>(); |
| registerPostProcessors(); |
| emfCompare = EMFCompare.builder().setPostProcessorRegistry(postProcessorRegistry).build(); |
| mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance(); |
| final IMerger umlMerger = new UMLMerger(); |
| umlMerger.setRanking(11); |
| final IMerger diagramMerger = new CompareDiagramMerger(); |
| diagramMerger.setRanking(11); |
| mergerRegistry.add(umlMerger); |
| mergerRegistry.add(diagramMerger); |
| } |
| |
| protected void registerPostProcessors() { |
| getPostProcessorRegistry().put(UMLPostProcessor.class.getName(), |
| new TestPostProcessor.TestPostProcessorDescriptor( |
| Pattern.compile("http://www.eclipse.org/uml2/\\d.0.0/UML"), null, |
| new UMLPostProcessor(), 20)); |
| getPostProcessorRegistry().put(CompareDiagramPostProcessor.class.getName(), |
| new TestPostProcessor.TestPostProcessorDescriptor( |
| Pattern.compile("http://www.eclipse.org/gmf/runtime/\\d.\\d.\\d/notation"), null, |
| new CompareDiagramPostProcessor(), 30)); |
| } |
| |
| protected EMFCompare getCompare() { |
| return emfCompare; |
| } |
| |
| /** |
| * @return the postProcessorRegistry |
| */ |
| protected PostProcessorDescriptorRegistryImpl<String> getPostProcessorRegistry() { |
| return postProcessorRegistry; |
| } |
| |
| protected IMerger.Registry getMergerRegistry() { |
| return mergerRegistry; |
| } |
| |
| protected Comparison buildComparison(Resource left, Resource right) { |
| final IComparisonScope2 scope = new DefaultComparisonScope(left.getResourceSet(), |
| right.getResourceSet(), null); |
| final Set<ResourceSet> resourceSets = ImmutableSet.of(left.getResourceSet(), right.getResourceSet()); |
| scope.getAllInvolvedResourceURIs().addAll(getResourceURIs(resourceSets)); |
| return EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build() |
| .compare(scope); |
| } |
| |
| protected Comparison buildComparison(Resource left, Resource right, Resource origin) { |
| final IComparisonScope2 scope = new DefaultComparisonScope(left.getResourceSet(), |
| right.getResourceSet(), origin.getResourceSet()); |
| final Set<ResourceSet> resourceSets = ImmutableSet.of(left.getResourceSet(), right.getResourceSet(), |
| origin.getResourceSet()); |
| scope.getAllInvolvedResourceURIs().addAll(getResourceURIs(resourceSets)); |
| return EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build() |
| .compare(scope); |
| } |
| |
| private Set<URI> getResourceURIs(final Set<ResourceSet> resourceSets) { |
| Builder<URI> uriBuilder = ImmutableSet.builder(); |
| for (ResourceSet set : resourceSets) { |
| for (Resource resource : set.getResources()) { |
| uriBuilder.add(resource.getURI()); |
| } |
| } |
| return uriBuilder.build(); |
| } |
| |
| @After |
| public void after() { |
| if (getInput() != null && getInput().getSets() != null) { |
| for (ResourceSet set : getInput().getSets()) { |
| cleanup(set); |
| } |
| } |
| } |
| |
| private void cleanup(ResourceSet resourceSet) { |
| for (Resource res : resourceSet.getResources()) { |
| res.unload(); |
| } |
| resourceSet.getResources().clear(); |
| } |
| |
| protected enum TestKind { |
| ADD, DELETE; |
| } |
| |
| protected static int count(List<Diff> differences, Predicate<? super Diff> p) { |
| int count = 0; |
| final Iterator<Diff> result = Iterators.filter(differences.iterator(), p); |
| while (result.hasNext()) { |
| count++; |
| result.next(); |
| } |
| return count; |
| } |
| |
| protected void diffsChecking(Comparison comparison, int totalDiffsNb, ExpectedStat... expectedStats) { |
| List<Diff> differences = comparison.getDifferences(); |
| assertEquals(totalDiffsNb, differences.size()); |
| for (ExpectedStat expectedStat : expectedStats) { |
| Predicate<Diff> p = expectedStat.p; |
| int nb = expectedStat.nb; |
| int result = Collections2.filter(differences, p).size(); |
| |
| String message = buildAssertMessage(differences, p); |
| |
| assertEquals(message, nb, result); |
| } |
| testIntersections(comparison); |
| } |
| |
| private String buildAssertMessage(Collection<Diff> differences, Predicate<Diff> p) { |
| Diff diff = Iterables.find(differences, p, null); |
| String message = ""; |
| if (diff != null) { |
| EClass clazz = getElementClass(diff); |
| if (clazz != null) { |
| message = clazz.getName() + " from " + diff.eClass().getName(); |
| } |
| } |
| return message; |
| } |
| |
| protected class ExpectedStat { |
| public Predicate<Diff> p; |
| |
| public int nb; |
| |
| public ExpectedStat(Predicate<Diff> p, int nb) { |
| this.p = p; |
| this.nb = nb; |
| } |
| } |
| |
| protected static Predicate<Diff> nameIs(final String name) { |
| return new Predicate<Diff>() { |
| public boolean apply(Diff input) { |
| if (input instanceof UMLDiff) { |
| EObject element = ((UMLDiff)input).getDiscriminant(); |
| if (element instanceof NamedElement) { |
| String eltName = ((NamedElement)element).getName(); |
| return name.equals(eltName); |
| } |
| } |
| return false; |
| } |
| |
| }; |
| } |
| |
| protected static Predicate<Diff> elementNameIs(final String name) { |
| return new Predicate<Diff>() { |
| public boolean apply(Diff input) { |
| if (input instanceof DiagramDiff) { |
| EObject obj = ((DiagramDiff)input).getView(); |
| if (obj instanceof View) { |
| EObject element = ((View)((DiagramDiff)input).getView()).getElement(); |
| if (element instanceof NamedElement) { |
| String eltName = ((NamedElement)element).getName(); |
| return name.equals(eltName); |
| } |
| } |
| } |
| return false; |
| } |
| |
| }; |
| } |
| |
| protected static Predicate<Diff> valueIs(final EClass clazz) { |
| return new Predicate<Diff>() { |
| public boolean apply(Diff input) { |
| return getValue(input) != null && getValue(input).eClass() == clazz; |
| } |
| }; |
| } |
| |
| protected static Predicate<Diff> elementClassIs(final EClass clazz) { |
| return new Predicate<Diff>() { |
| public boolean apply(Diff input) { |
| return getElementClass(input) == clazz; |
| } |
| |
| }; |
| } |
| |
| protected static Predicate<Diff> discriminantInstanceOf(final EClass clazz) { |
| return new Predicate<Diff>() { |
| public boolean apply(Diff input) { |
| return input instanceof UMLDiff && clazz.isInstance(((UMLDiff)input).getDiscriminant()); |
| } |
| |
| }; |
| } |
| |
| protected static EObject getValue(Diff diff) { |
| if (diff instanceof DiagramDiff) { |
| return ((DiagramDiff)diff).getView(); |
| } else if (diff instanceof UMLDiff) { |
| return ((UMLDiff)diff).getDiscriminant(); |
| } else if (diff instanceof ReferenceChange) { |
| return ((ReferenceChange)diff).getValue(); |
| } |
| return null; |
| } |
| |
| protected static EClass getElementClass(Diff diff) { |
| EObject obj = getValue(diff); |
| if (obj instanceof View) { |
| EObject element = ((View)obj).getElement(); |
| if (element != null) { |
| return element.eClass(); |
| } |
| } |
| if (obj != null) { |
| return obj.eClass(); |
| } |
| return null; |
| } |
| |
| protected abstract DiagramInputData getInput(); |
| |
| protected void testIntersections(Comparison comparison) { |
| assertFalse(Iterables.any(comparison.getDifferences(), new Predicate<Diff>() { |
| public boolean apply(Diff input) { |
| return input.getRefines().size() > 1; |
| } |
| })); |
| } |
| |
| } |