// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.cwm.compare; import java.util.Iterator; import org.eclipse.emf.common.util.Monitor; import org.eclipse.emf.compare.Comparison; import org.eclipse.emf.compare.match.DefaultMatchEngine; import org.eclipse.emf.compare.match.IComparisonFactory; import org.eclipse.emf.compare.match.eobject.CachingDistance; import org.eclipse.emf.compare.match.eobject.IEObjectMatcher; import org.eclipse.emf.compare.match.eobject.IdentifierEObjectMatcher; import org.eclipse.emf.compare.match.eobject.ProximityEObjectMatcher; import org.eclipse.emf.compare.match.eobject.WeightProvider; import org.eclipse.emf.compare.match.eobject.WeightProviderDescriptorRegistryImpl; import org.eclipse.emf.compare.scope.IComparisonScope; import org.eclipse.emf.compare.utils.UseIdentifiers; import org.eclipse.emf.ecore.EObject; import org.talend.core.model.metadata.builder.connection.DatabaseConnection; import org.talend.cwm.helper.SwitchHelpers; import com.google.common.collect.Iterators; /** * created by talend on 2015-07-28 Detailled comment. * */ public class ModelElementMatchEngine extends DefaultMatchEngine { /** * DOC qiongli ModelElementMatchEngine constructor comment. * * @param matcher * @param comparisonFactory */ public ModelElementMatchEngine(IEObjectMatcher matcher, IComparisonFactory comparisonFactory) { super(matcher, comparisonFactory); } /** * Creates and configures an {@link IEObjectMatcher} with the strategy given by {@code useIDs}. The {@code cache} * will be used to cache some expensive computation (should better a LoadingCache). * * @param useIDs which strategy the return IEObjectMatcher must follow. * @return a new IEObjectMatcher. */ public static IEObjectMatcher createDQEObjectMatcher(UseIdentifiers useIDs) { return createDQEObjectMatcher(useIDs, WeightProviderDescriptorRegistryImpl.createStandaloneInstance()); } /** * Creates and configures an {@link IEObjectMatcher} with the strategy given by {@code useIDs}. The {@code cache} * will be used to cache some expensive computation (should better a LoadingCache). * * @param useIDs which strategy the return IEObjectMatcher must follow. * @param weightProviderRegistry the match engine needs a WeightProvider in case of this match engine do not use * identifiers. * @return a new IEObjectMatcher. */ public static IEObjectMatcher createDQEObjectMatcher(UseIdentifiers useIDs, WeightProvider.Descriptor.Registry weightProviderRegistry) { final IEObjectMatcher matcher; final ModelElementEditonDistance editionDistance = new ModelElementEditonDistance(weightProviderRegistry); final CachingDistance cachedDistance = new CachingDistance(editionDistance); switch (useIDs) { case NEVER: matcher = new ProximityEObjectMatcher(cachedDistance); break; case ONLY: matcher = new IdentifierEObjectMatcher(); break; case WHEN_AVAILABLE: // fall through to default default: // Use an ID matcher, delegating to proximity when no ID is available final IEObjectMatcher contentMatcher = new ProximityEObjectMatcher(cachedDistance); matcher = new IdentifierEObjectMatcher(contentMatcher); break; } return matcher; } /* * (non-Javadoc) * * @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) { DatabaseConnection dbConnLeft = SwitchHelpers.DATABASECONNECTION_SWITCH.doSwitch(left); DatabaseConnection dbConnRight = SwitchHelpers.DATABASECONNECTION_SWITCH.doSwitch(right); if (dbConnLeft != null && dbConnRight != null) { matchForDBConn(comparison, scope, left, right, origin, monitor); return; } super.match(comparison, scope, left, right, origin, monitor); } /** * * if the scope is DBConnection,should use scope.getCoveredEObjects(EResource res),instead of * scope.getChildren(EObject left). * * @param comparison * @param scope * @param left * @param right * @param origin * @param monitor */ private void matchForDBConn(Comparison comparison, IComparisonScope scope, EObject left, EObject right, EObject origin, Monitor monitor) { if (left == null || right == null) { throw new IllegalArgumentException(); } final Iterator<? extends EObject> leftEObjects = Iterators.concat(Iterators.singletonIterator(left), scope.getCoveredEObjects(left.eResource())); final Iterator<? extends EObject> rightEObjects = Iterators.concat(Iterators.singletonIterator(right), scope.getCoveredEObjects(right.eResource())); final Iterator<? extends EObject> originEObjects; if (origin != null) { originEObjects = Iterators.concat(Iterators.singletonIterator(origin), scope.getCoveredEObjects(origin.eResource())); } else { originEObjects = Iterators.emptyIterator(); } getEObjectMatcher().createMatches(comparison, leftEObjects, rightEObjects, originEObjects, monitor); } }