/******************************************************************************* * Copyright (c) 2014 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.eobject; import com.google.common.collect.Maps; import java.util.Map; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; /** * The default implementation of {@link org.eclipse.emf.compare.match.eobject.WeightProvider} applicable to * all objects. * * @since 3.1.0 * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a> */ public class DefaultWeightProvider extends AbstractWeightProvider { /** * The list of specific weight to apply on specific Features. */ protected Map<EStructuralFeature, Integer> weights; /** * Weight coefficient of a change on a reference. */ protected int referenceChangeCoef = NORMAL; /** * Weight coefficient of a change on an attribute. */ protected int attributeChangeCoef = SIGNIFICANT; /** * Create the weight provider. */ public DefaultWeightProvider() { weights = Maps.newHashMap(); } /** * {@inheritDoc} */ public int getWeight(EStructuralFeature feature) { if (irrelevant(feature)) { return 0; } Integer found = weights.get(feature); if (found == null) { found = Integer.valueOf(SMALL); /* * This is worst than empirical but it works in many cases, if your feature is a "name" its likely * that it's important for matching the element. At some point I'll have to come up with something * which is more extensible.. */ if ("name".equals(feature.getName()) || "id".equals(feature.getName())) { //$NON-NLS-1$ //$NON-NLS-2$ found = Integer.valueOf(SIGNIFICANT); } if (feature instanceof EReference) { found = Integer.valueOf(referenceChangeCoef * found.intValue()); } else { found = Integer.valueOf(attributeChangeCoef * found.intValue()); } weights.put(feature, found); } return found.intValue(); } /** * {@inheritDoc} */ public int getParentWeight(EObject a) { return SIGNIFICANT; } /** * {@inheritDoc} */ public int getContainingFeatureWeight(EObject a) { return NORMAL; } /** * return true i the feature is irrelevant for the comparison. * * @param feat * any feature. * @return true i the feature is irrelevant for the comparison. */ protected boolean irrelevant(EStructuralFeature feat) { if (feat instanceof EAttribute) { return feat.isDerived() || feat.isTransient(); } else { EReference ref = (EReference)feat; return ref.isDerived() || ref.isTransient() || ref.isContainment() || ref.isContainer(); } } }