/******************************************************************************* * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Obeo - initial API and implementation *******************************************************************************/ package data.models; import static com.google.common.collect.Lists.newArrayList; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Collections; import java.util.List; import org.eclipse.compare.ITypedElement; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.util.BasicMonitor; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.compare.Comparison; import org.eclipse.emf.compare.EMFCompare; import org.eclipse.emf.compare.conflict.MatchBasedConflictDetector; import org.eclipse.emf.compare.conflict.IConflictDetector; import org.eclipse.emf.compare.diagram.internal.CompareDiagramPostProcessor; import org.eclipse.emf.compare.diff.DefaultDiffEngine; import org.eclipse.emf.compare.diff.DiffBuilder; import org.eclipse.emf.compare.diff.IDiffEngine; import org.eclipse.emf.compare.diff.IDiffProcessor; import org.eclipse.emf.compare.equi.DefaultEquiEngine; import org.eclipse.emf.compare.equi.IEquiEngine; import org.eclipse.emf.compare.ide.ui.internal.logical.ComparisonScopeBuilder; import org.eclipse.emf.compare.match.DefaultMatchEngine; import org.eclipse.emf.compare.match.IMatchEngine; import org.eclipse.emf.compare.postprocessor.IPostProcessor; import org.eclipse.emf.compare.req.DefaultReqEngine; import org.eclipse.emf.compare.req.IReqEngine; import org.eclipse.emf.compare.scope.DefaultComparisonScope; import org.eclipse.emf.compare.scope.IComparisonScope; import org.eclipse.emf.compare.uml2.internal.postprocessor.UMLPostProcessor; import org.eclipse.emf.compare.utils.UseIdentifiers; import org.eclipse.emf.ecore.EObject; 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.util.EcoreUtil; import org.eclipse.uml2.uml.UMLPackage; import org.eclipse.uml2.uml.resource.UMLResource; import com.google.common.io.Closeables; public abstract class Data { private List<ResourceSet> resourceSets = newArrayList(); private Comparison comparison; private final Notifier left; private final Notifier right; private final Notifier ancestor; public abstract Notifier loadLeft(); public abstract Notifier loadRight(); public abstract Notifier loadAncestor(); /** * */ protected Data() { left = loadLeft(); right = loadRight(); ancestor = loadAncestor(); } /** * @return the left */ public Notifier getLeft() { return left; } /** * @return the right */ public Notifier getRight() { return right; } /** * @return the ancestor */ public Notifier getAncestor() { return ancestor; } protected ResourceSet createResourceSet() { ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE); resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE); resourceSets.add(resourceSet); return resourceSet; } public void logicalModel(ITypedElement leftTypedElement, ITypedElement rightTypedElement) { ComparisonScopeBuilder.create(null, leftTypedElement, rightTypedElement, null, new NullProgressMonitor()); } public Comparison match() { return match(UseIdentifiers.ONLY); } public Comparison match(UseIdentifiers useIDs) { final IComparisonScope scope = new DefaultComparisonScope(getLeft(), getRight(), getAncestor()); final IMatchEngine matchEngine = DefaultMatchEngine.create(useIDs); comparison = matchEngine.match(scope, new BasicMonitor()); return comparison; } public Comparison diff() { final IDiffProcessor diffBuilder = new DiffBuilder(); final IDiffEngine diffEngine = new DefaultDiffEngine(diffBuilder); diffEngine.diff(comparison, new BasicMonitor()); return comparison; } public void req() { final IReqEngine reqEngine = new DefaultReqEngine(); reqEngine.computeRequirements(comparison, new BasicMonitor()); } public void equi() { final IEquiEngine equiEngine = new DefaultEquiEngine(); equiEngine.computeEquivalences(comparison, new BasicMonitor()); } public void conflict() { final IConflictDetector conflictDetector = new MatchBasedConflictDetector(); conflictDetector.detect(comparison, new BasicMonitor()); } public void compare() { final IComparisonScope scope = new DefaultComparisonScope(getLeft(), getRight(), getAncestor()); EMFCompare.builder().build().compare(scope); } public void postComparisonGMF() { final IPostProcessor postProcessor = new CompareDiagramPostProcessor(); postProcessor.postComparison(comparison, new BasicMonitor()); } public void postMatchUML() { final IPostProcessor postProcessor = new UMLPostProcessor(); postProcessor.postMatch(comparison, new BasicMonitor()); } public void postComparisonUML() { final IPostProcessor postProcessor = new UMLPostProcessor(); postProcessor.postComparison(comparison, new BasicMonitor()); } public void dispose() { comparison = null; for (ResourceSet rs : resourceSets) { EList<Resource> resources = rs.getResources(); for (Resource resource : resources) { TreeIterator<EObject> allContents = EcoreUtil.getAllProperContents(resource, false); while (allContents.hasNext()) { final EObject next = allContents.next(); next.eAdapters().clear(); } resource.eAdapters().clear(); } rs.getResources().clear(); rs.eAdapters().clear(); } resourceSets = null; } /** * Tries and locate a model in the current class' classpath. * * @param string * Relative path to the model we seek (relative to this class). * @param resourceSet * the resource set in which to load the resource. * @return The loaded resource. * @throws IOException * Thrown if we could not access either this class' resource, or the file towards which * <code>path</code> points. */ // Suppressing the warning until bug 376938 is fixed protected Resource loadFromClassLoader(String path, ResourceSet resourceSet) { final URL fileURL = getClass().getResource(path); final URI uri = URI.createURI(fileURL.toString()); final Resource existing = resourceSet.getResource(uri, false); if (existing != null) { return existing; } InputStream stream = null; Resource resource = null; try { resource = resourceSet.createResource(uri); stream = fileURL.openStream(); resource.load(stream, Collections.emptyMap()); } catch (IOException e) { // return null } catch (WrappedException e) { // return null } finally { try { Closeables.close(stream, true); } catch (IOException e) { // already swallowed } } return resource; } }