/******************************************************************************* * 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.emf.compare.match.resource; import com.google.common.collect.Lists; import java.util.List; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.compare.CompareFactory; import org.eclipse.emf.compare.MatchResource; import org.eclipse.emf.ecore.resource.Resource; /** * This implementation of a matching strategy will only use String equality on the resource names to try and * find resource mappings. * * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a> */ public class NameMatchingStrategy implements IResourceMatchingStrategy { /** * {@inheritDoc} * * @see org.eclipse.emf.compare.match.resource.IResourceMatchingStrategy#matchResources(java.lang.Iterable, * java.lang.Iterable, java.lang.Iterable) */ public List<MatchResource> matchResources(Iterable<? extends Resource> left, Iterable<? extends Resource> right, Iterable<? extends Resource> origin) { final List<MatchResource> mappings = Lists.newArrayList(); final List<Resource> rightCopy = Lists.newArrayList(right); final List<Resource> originCopy = Lists.newArrayList(origin); // Can we find matches for the left resource in either left or origin? for (Resource leftResource : left) { final Resource matchingRight = findMatch(leftResource, rightCopy); final Resource matchingOrigin = findMatch(leftResource, originCopy); if (matchingRight != null || matchingOrigin != null) { rightCopy.remove(matchingRight); originCopy.remove(matchingOrigin); mappings.add(createMatchResource(leftResource, matchingRight, matchingOrigin)); } } // We no longer have to check in the left, but we may have matches of the right resources in the // origin list for (Resource rightResource : rightCopy) { final Resource matchingOrigin = findMatch(rightResource, originCopy); originCopy.remove(matchingOrigin); if (matchingOrigin != null) { mappings.add(createMatchResource(null, rightResource, matchingOrigin)); } } return mappings; } /** * Returns the first match of <code>reference</code> in <code>candidates</code>. This implementation will * consider two Resources to be "matches" if they have the same name. * * @param reference * The reference resource. * @param candidates * The list of potential candidates that may match <code>reference</code>. * @return The first match of <code>reference</code> in <code>candidates</code>. <code>null</code> if * none. */ protected Resource findMatch(Resource reference, Iterable<Resource> candidates) { final URI referenceURI = reference.getURI(); for (Resource candidate : candidates) { if (urisLastSegmentMatch(referenceURI, candidate.getURI())) { return candidate; } } return null; } /** * Indicates whether the given URIs are equal or have the same last segment. * * @param referenceURI * Reference URI * @param otherURI * Candidate URI * @return <code>true</code> if both URIs are null, or if they are equal, or if they have the same * non-null last segment. */ private boolean urisLastSegmentMatch(URI referenceURI, URI otherURI) { if (referenceURI == otherURI) { return true; } if (referenceURI != null && otherURI != null) { if (referenceURI.equals(otherURI)) { return true; } String lastSegment = referenceURI.lastSegment(); return lastSegment != null && lastSegment.equals(otherURI.lastSegment()); } return false; } /** * Creates a {@link MatchResource} instance and sets all three resources of the mapping on it. * * @param left * The left resource of this mapping. * @param right * The right resource of this mapping. * @param origin * The origin resource of this mapping. * @return The create mapping. */ protected static MatchResource createMatchResource(Resource left, Resource right, Resource origin) { final MatchResource match = CompareFactory.eINSTANCE.createMatchResource(); match.setLeft(left); match.setRight(right); match.setOrigin(origin); if (left != null && left.getURI() != null) { match.setLeftURI(left.getURI().toString()); } if (right != null && right.getURI() != null) { match.setRightURI(right.getURI().toString()); } if (origin != null && origin.getURI() != null) { match.setOriginURI(origin.getURI().toString()); } return match; } }