blob: d404c322cdd9e28555c781f9a0df287824b4f95c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 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.mylyn.docs.intent.compare.utils;
import com.google.common.base.Predicates;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.EMFCompare.Builder;
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.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.IMatchEngine.Factory.Registry;
import org.eclipse.emf.compare.match.eobject.IEObjectMatcher;
import org.eclipse.emf.compare.match.eobject.ProximityEObjectMatcher;
import org.eclipse.emf.compare.match.impl.MatchEngineFactoryImpl;
import org.eclipse.emf.compare.match.impl.MatchEngineFactoryRegistryImpl;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.utils.UseIdentifiers;
import org.eclipse.mylyn.docs.intent.compare.match.EditionDistance;
import org.eclipse.mylyn.docs.intent.compare.scope.IntentComparisonScope;
import org.eclipse.mylyn.docs.intent.core.compiler.CompilationStatus;
import org.eclipse.mylyn.docs.intent.core.compiler.SynchronizerCompilationStatus;
/**
* Utilities for EMF Compare use.
*
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
*/
public final class EMFCompareUtils {
/**
* A {@link Registry} always returning a Match engine ignoring identifiers.
*/
private static Registry neverUsingIdentifiersMatchEngine;
/**
* Prevents instantiation.
*/
private EMFCompareUtils() {
}
/**
* Returns the differences between the left element and the right element. Comparison customization:
* <ul>
* <li>Ignore XMI Ids</li>
* <li>Resolve proxies</li>
* </ul>
*
* @param left
* the left element
* @param right
* the right element
* @return the differences between the left element and the right element
*/
public static Comparison compare(Notifier left, Notifier right) {
IntentComparisonScope scope = new IntentComparisonScope(left, right);
Builder builder = EMFCompare.builder();
builder.setMatchEngineFactoryRegistry(getMatchEngineNeverUsingIdentifiers());
return builder.build().compare(scope);
}
/**
* Returns the differences between the left element and the right element. Comparison customization:
* <ul>
* <li>Ignore XMI Ids</li>
* <li>Resolve proxies</li>
* <li>Intent specific match engine</li>
* </ul>
*
* @param left
* the left element
* @param right
* the right element
* @return the differences between the left element and the right element
*/
public static Comparison compareDocuments(Notifier left, Notifier right) {
// Step 1: create comparison scope
IntentComparisonScope scope = new IntentComparisonScope(left, right);
scope.setEObjectContentFilter(Predicates.not(Predicates.or(
Predicates.instanceOf(CompilationStatus.class),
Predicates.instanceOf(SynchronizerCompilationStatus.class))));
// Step 2: initialize match & diff engine
Registry matchEngine = getIntentDocumentMatchEngine(left, right);
DefaultDiffEngine diffEngine = new DefaultDiffEngine(new DiffBuilder()) {
@Override
protected FeatureFilter createFeatureFilter() {
return new IntentFeatureFilter();
}
};
// Step 3: launch comparison
Builder builder = EMFCompare.builder();
builder.setDiffEngine(diffEngine);
builder.setMatchEngineFactoryRegistry(matchEngine);
return builder.build().compare(scope);
}
/**
* Returns a {@link Registry} always returning a Match engine ignoring identifiers.
*
* @return a {@link Registry} always returning a Match engine ignoring identifiers
*/
public static Registry getMatchEngineNeverUsingIdentifiers() {
if (neverUsingIdentifiersMatchEngine == null) {
IMatchEngine matchEngine = DefaultMatchEngine.create(UseIdentifiers.NEVER);
neverUsingIdentifiersMatchEngine = createMatchEngineRegistryFromMatchEngine(matchEngine);
}
return neverUsingIdentifiersMatchEngine;
}
/**
* Returns a {@link Registry} always returning a Match engine allowing to compare 2 intent documents with
* the given left and right roots.
*
* @param left
* the left root of the Intent element (parsed from current editor)
* @param right
* the right root of the Intent element (from Intent repository)
* @return a {@link Registry} always returning a Match engine allowing to compare 2 intent documents with
* the given left and right roots
*/
private static Registry getIntentDocumentMatchEngine(Notifier left, Notifier right) {
IEObjectMatcher matcher = new ProximityEObjectMatcher(EditionDistance.builder(left, right).build());
final IComparisonFactory comparisonFactory = new DefaultComparisonFactory(
new DefaultEqualityHelperFactory());
IMatchEngine matchEngine = new DefaultMatchEngine(matcher, comparisonFactory);
return createMatchEngineRegistryFromMatchEngine(matchEngine);
}
/**
* Returns a {@link Registry} always returning the given {@link IMatchEngine}.
*
* @param matchEngineToUse
* the {@link IMatchEngine} to return
* @return a {@link Registry} always returning the given {@link IMatchEngine}
*/
private static Registry createMatchEngineRegistryFromMatchEngine(final IMatchEngine matchEngineToUse) {
Registry matchEngineFactoryRegistry = new MatchEngineFactoryRegistryImpl();
MatchEngineFactoryImpl matchEngineFactory = new MatchEngineFactoryImpl() {
@Override
public IMatchEngine getMatchEngine() {
return matchEngineToUse;
}
@Override
public boolean isMatchEngineFactoryFor(IComparisonScope scope) {
return true;
}
};
matchEngineFactoryRegistry.add(matchEngineFactory);
return matchEngineFactoryRegistry;
}
}