| /******************************************************************************* |
| * 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 org.eclipse.emf.compare.ide.ui.internal.handler; |
| |
| import static java.util.Collections.emptyIterator; |
| |
| import java.util.Iterator; |
| |
| import org.eclipse.compare.CompareConfiguration; |
| import org.eclipse.compare.CompareEditorInput; |
| import org.eclipse.core.commands.AbstractHandler; |
| import org.eclipse.emf.common.command.CommandStack; |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.common.notify.Notifier; |
| import org.eclipse.emf.common.util.Monitor; |
| import org.eclipse.emf.compare.CompareFactory; |
| import org.eclipse.emf.compare.Comparison; |
| import org.eclipse.emf.compare.EMFCompare; |
| import org.eclipse.emf.compare.EMFCompare.Builder; |
| import org.eclipse.emf.compare.Match; |
| import org.eclipse.emf.compare.domain.ICompareEditingDomain; |
| import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain; |
| import org.eclipse.emf.compare.ide.ui.internal.configuration.EMFCompareConfiguration; |
| import org.eclipse.emf.compare.ide.ui.internal.editor.ComparisonScopeEditorInput; |
| import org.eclipse.emf.compare.match.DefaultComparisonFactory; |
| import org.eclipse.emf.compare.match.DefaultEqualityHelperFactory; |
| import org.eclipse.emf.compare.match.DefaultMatchEngine; |
| import org.eclipse.emf.compare.match.IComparisonFactory; |
| import org.eclipse.emf.compare.match.IMatchEngine; |
| import org.eclipse.emf.compare.match.eobject.IEObjectMatcher; |
| import org.eclipse.emf.compare.match.impl.MatchEngineFactoryImpl; |
| import org.eclipse.emf.compare.provider.AdapterFactoryUtil; |
| import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; |
| import org.eclipse.emf.compare.rcp.internal.extension.impl.EMFCompareBuilderConfigurator; |
| import org.eclipse.emf.compare.scope.DefaultComparisonScope; |
| import org.eclipse.emf.compare.scope.IComparisonScope; |
| import org.eclipse.emf.compare.utils.UseIdentifiers; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.edit.domain.IEditingDomainProvider; |
| import org.eclipse.emf.edit.provider.IDisposable; |
| import org.eclipse.ui.IWorkbenchPart; |
| |
| /** |
| * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a> |
| */ |
| public abstract class AbstractCompareHandler extends AbstractHandler { |
| |
| protected static CompareEditorInput createCompareEditorInput(IWorkbenchPart part, |
| AdapterFactory adapterFactory, Notifier left, Notifier right, Notifier origin) { |
| CompareEditorInput input = null; |
| |
| final ICompareEditingDomain editingDomain = createEMFCompareEditingDomain(part, left, right, origin); |
| |
| final EMFCompareConfiguration configuration = new EMFCompareConfiguration(new CompareConfiguration()); |
| IMatchEngine.Factory eObjectMatchEngineFactory = new MatchEObjectEngineFactory(); |
| eObjectMatchEngineFactory.setRanking(0); |
| final IMatchEngine.Factory.Registry matchEngineFactoryRegistry = EMFCompareRCPPlugin.getDefault() |
| .getMatchEngineFactoryRegistry(); |
| matchEngineFactoryRegistry.add(eObjectMatchEngineFactory); |
| |
| final Builder builder = EMFCompare.builder(); |
| EMFCompareBuilderConfigurator engineProvider = EMFCompareBuilderConfigurator.createDefault(); |
| engineProvider.configure(builder); |
| EMFCompare comparator = builder.build(); |
| |
| IComparisonScope scope = new DefaultComparisonScope(left, right, origin); |
| input = new ComparisonScopeEditorInput(configuration, editingDomain, adapterFactory, comparator, |
| scope) { |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.compare.CompareEditorInput#handleDispose() |
| */ |
| @Override |
| protected void handleDispose() { |
| super.handleDispose(); |
| if (editingDomain instanceof IDisposable) { |
| ((IDisposable)editingDomain).dispose(); |
| } |
| matchEngineFactoryRegistry.remove(MatchEObjectEngineFactory.class.getName()); |
| } |
| }; |
| |
| input.setTitle("Compare ('" + AdapterFactoryUtil.getText(adapterFactory, left) + "' - '" |
| + AdapterFactoryUtil.getText(adapterFactory, right) + "')"); |
| |
| configuration.setContainer(input); |
| return input; |
| } |
| |
| private static ICompareEditingDomain createEMFCompareEditingDomain(final IWorkbenchPart activePart, |
| final Notifier left, final Notifier right, Notifier origin) { |
| |
| EditingDomain delegatingEditingDomain = getDelegatingEditingDomain(activePart, left, right); |
| CommandStack delegatingCommandStack = null; |
| if (delegatingEditingDomain != null) { |
| delegatingCommandStack = delegatingEditingDomain.getCommandStack(); |
| } |
| |
| if (delegatingCommandStack == null) { |
| return EMFCompareEditingDomain.create(left, right, origin); |
| } else { |
| return EMFCompareEditingDomain.create(left, right, origin, delegatingCommandStack); |
| } |
| } |
| |
| private static EditingDomain getDelegatingEditingDomain(final IWorkbenchPart activePart, Notifier left, |
| Notifier right) { |
| EditingDomain delegatingEditingDomain = null; |
| if (activePart instanceof IEditingDomainProvider) { |
| delegatingEditingDomain = ((IEditingDomainProvider)activePart).getEditingDomain(); |
| } else if (AdapterFactoryEditingDomain.getEditingDomainFor(left) != null) { |
| EditingDomain leftEditingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(left); |
| EditingDomain rightEditingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(right); |
| // do not use a delegating editing domain if those two are different. |
| if (leftEditingDomain == rightEditingDomain) { |
| delegatingEditingDomain = leftEditingDomain; |
| } |
| } |
| return delegatingEditingDomain; |
| } |
| |
| /** |
| * A specialized {@link MatchEngineFactoryImpl} that wrap a {@link MatchEObjectEngine}. |
| * |
| * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a> |
| */ |
| private static class MatchEObjectEngineFactory extends MatchEngineFactoryImpl { |
| |
| /** |
| * Default Constructor. |
| */ |
| public MatchEObjectEngineFactory() { |
| matchEngine = new MatchEObjectEngine(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.compare.match.IMatchEngine.Factory.isMatchEngineFactoryFor(org.eclipse.emf. |
| * compare .scope.IComparisonScope) |
| */ |
| @Override |
| public boolean isMatchEngineFactoryFor(IComparisonScope scope) { |
| final Notifier left = scope.getLeft(); |
| final Notifier right = scope.getRight(); |
| final Notifier origin = scope.getOrigin(); |
| if (left instanceof EObject && right instanceof EObject |
| && (origin == null || origin instanceof EObject)) { |
| return true; |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * A specialized {@link DefaultMatchEngine} for comparison between EObjects. |
| * |
| * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a> |
| */ |
| private static class MatchEObjectEngine extends DefaultMatchEngine { |
| |
| /** |
| * Default Constructor. |
| */ |
| public MatchEObjectEngine() { |
| // never use id in EObjects comparison |
| super(DefaultMatchEngine.createDefaultEObjectMatcher(UseIdentifiers.NEVER, |
| EMFCompareRCPPlugin.getDefault().getWeightProviderRegistry()), |
| new DefaultComparisonFactory(new DefaultEqualityHelperFactory())); |
| } |
| |
| /** |
| * Constructor with matcher and comparison factory parameters. |
| * |
| * @param matcher |
| * The matcher that will be in charge of pairing EObjects together for this comparison |
| * process. |
| * @param comparisonFactory |
| * factory that will be use to instantiate Comparison as return by match() methods. |
| */ |
| public MatchEObjectEngine(IEObjectMatcher matcher, IComparisonFactory comparisonFactory) { |
| super(matcher, comparisonFactory); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.emf.compare.match.DefaultMatchEngine.match(org.eclipse.emf.compare.Comparison, |
| * org.eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.ecore.EObject, |
| * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject, |
| * org.eclipse.emf.common.util.Monitor) |
| */ |
| @Override |
| protected void match(Comparison comparison, IComparisonScope scope, EObject left, EObject right, |
| EObject origin, Monitor monitor) { |
| if (left == null || right == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| Match rootMatch = CompareFactory.eINSTANCE.createMatch(); |
| rootMatch.setLeft(left); |
| rootMatch.setRight(right); |
| rootMatch.setOrigin(origin); |
| comparison.getMatches().add(rootMatch); |
| |
| final Iterator<? extends EObject> leftEObjects = scope.getChildren(left); |
| final Iterator<? extends EObject> rightEObjects = scope.getChildren(right); |
| final Iterator<? extends EObject> originEObjects; |
| if (origin != null) { |
| originEObjects = scope.getChildren(origin); |
| } else { |
| originEObjects = emptyIterator(); |
| } |
| |
| getEObjectMatcher().createMatches(comparison, leftEObjects, rightEObjects, originEObjects, |
| monitor); |
| |
| } |
| } |
| } |