Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbrun2012-10-10 20:46:00 +0000
committercbrun2012-10-10 20:46:00 +0000
commit43c798eace0eeeb8ad8b623c250401a0409af277 (patch)
tree8c5a17cef695c314377d3c078fa122c26a56ef2e
parent9d9c5582ab22362bf02786e7472cb1e2d2365fc7 (diff)
downloadorg.eclipse.emf.compare-43c798eace0eeeb8ad8b623c250401a0409af277.tar.gz
org.eclipse.emf.compare-43c798eace0eeeb8ad8b623c250401a0409af277.tar.xz
org.eclipse.emf.compare-43c798eace0eeeb8ad8b623c250401a0409af277.zip
Bug 390664 - ignore XMI id option does not fully ignore ids
https://bugs.eclipse.org/bugs/show_bug.cgi?id=390664 With this commit the structure based matching is no more comparing URIs to evaluate the location of an EObject. The problem was some URI could contain reference to an ID and so even if you want to ignore IDs it would have an effect on the computation. It's just a first step though as the EqualityHelper which is indirectly used by the EditionDistance (through the DiffEngine) is still using URIs to compare EObjects.
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/ProximityComparisonTest.java36
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/DistanceMatchInputData.java32
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-super.ecore8
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-superv2.ecore8
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norename.ecore7
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norenamev2.ecore8
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-delete.ecore8
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-deletev2.ecore11
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-delete.ecore7
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-deletev2.ecore6
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EditionDistance.java14
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/URIDistance.java127
12 files changed, 264 insertions, 8 deletions
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/ProximityComparisonTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/ProximityComparisonTest.java
index 12ca1de53..e06d23085 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/ProximityComparisonTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/ProximityComparisonTest.java
@@ -15,13 +15,19 @@ import static org.junit.Assert.assertEquals;
import com.google.common.collect.Lists;
+import java.util.List;
+
import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.compare.tests.framework.EMFCompareAssert;
import org.eclipse.emf.compare.tests.framework.EMFCompareTestBase;
import org.eclipse.emf.compare.tests.fullcomparison.data.distance.DistanceMatchInputData;
import org.eclipse.emf.compare.tests.suite.AllTests;
+import org.eclipse.emf.compare.utils.EMFComparePrettyPrinter;
import org.eclipse.emf.compare.utils.UseIdentifiers;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
@@ -85,7 +91,35 @@ public class ProximityComparisonTest extends EMFCompareTestBase {
final IComparisonScope scope = EMFCompare.createDefaultScope(v1, v2);
Comparison result = EMFCompare.newComparator(scope).matchByID(UseIdentifiers.NEVER).compare();
assertAllMatched(Lists.newArrayList(v1), result);
- assertEquals("We are supposed to have zero diffs", 1, result.getDifferences().size());
+ assertEquals("We are supposed to have a rename", 1, result.getDifferences().size());
+ }
+
+ @Test
+ public void packageAddDelete() throws Exception {
+ final IComparisonScope scope = EMFCompare.createDefaultScope(inputData.getPackageAddDeleteLeft(),
+ inputData.getPackageAddDeleteRight());
+ Comparison result = EMFCompare.newComparator(scope).matchByID(UseIdentifiers.NEVER).compare();
+ EMFComparePrettyPrinter.printComparison(result, System.out);
+ final List<Diff> differences = result.getDifferences();
+ EMFCompareAssert.assertAddedToReference(differences, "p1.p2", "eSubpackages", "p1.p2.subPackage",
+ DifferenceSource.LEFT);
+ EMFCompareAssert.assertRemovedFromReference(differences, "p1", "eSubpackages", "p1.another",
+ DifferenceSource.LEFT);
+ assertEquals("We are supposed to have zero diffs", 2, result.getDifferences().size());
+ }
+
+ @Test
+ public void packageAddRemoveNoRename() throws Exception {
+ final IComparisonScope scope = EMFCompare.createDefaultScope(inputData
+ .getPackageAddRemoveNoRenameLeft(), inputData.getPackageAddRemoveNoRenameRight());
+ Comparison result = EMFCompare.newComparator(scope).matchByID(UseIdentifiers.NEVER).compare();
+ EMFComparePrettyPrinter.printComparison(result, System.out);
+ final List<Diff> differences = result.getDifferences();
+ // EMFCompareAssert.assertAddedToReference(differences, "p1.p2", "eSubpackages", "p1.p2.subPackage",
+ // DifferenceSource.LEFT);
+ // EMFCompareAssert.assertRemovedFromReference(differences, "p1", "eSubpackages", "p1.another",
+ // DifferenceSource.LEFT);
+ assertEquals("We are supposed to have zero diffs", 2, result.getDifferences().size());
}
@Test
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/DistanceMatchInputData.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/DistanceMatchInputData.java
index 1eb5686aa..0833b30d4 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/DistanceMatchInputData.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/DistanceMatchInputData.java
@@ -45,4 +45,36 @@ public class DistanceMatchInputData extends AbstractInputData {
return loadFromClassLoader("verySmallRight.ecore");
}
+ public Resource getPackageAddDeleteLeft() throws IOException {
+ return loadFromClassLoader("package-add-delete.ecore");
+ }
+
+ public Resource getPackageAddDeleteRight() throws IOException {
+ return loadFromClassLoader("package-add-deletev2.ecore");
+ }
+
+ public Resource getAbstractAndSuperLeft() throws IOException {
+ return loadFromClassLoader("abstract-and-super.ecore");
+ }
+
+ public Resource getAbstractAndSuperRight() throws IOException {
+ return loadFromClassLoader("abstract-and-superv2.ecore");
+ }
+
+ public Resource getFeatureUpdateDeleteLeft() throws IOException {
+ return loadFromClassLoader("feature-update-delete.ecore");
+ }
+
+ public Resource getFeatureUpdateDeleteRight() throws IOException {
+ return loadFromClassLoader("feature-update-deletev2.ecore");
+ }
+
+ public Resource getPackageAddRemoveNoRenameLeft() throws IOException {
+ return loadFromClassLoader("add-remove-norename.ecore");
+ }
+
+ public Resource getPackageAddRemoveNoRenameRight() throws IOException {
+ return loadFromClassLoader("add-remove-norenamev2.ecore");
+ }
+
}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-super.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-super.ecore
new file mode 100644
index 000000000..34fa94850
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-super.ecore
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="pak"
+ nsPrefix="pak">
+ <eClassifiers xsi:type="ecore:EClass" name="SomeClass" abstract="true" eSuperTypes="#//Master"/>
+ <eClassifiers xsi:type="ecore:EClass" name="Master"/>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-superv2.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-superv2.ecore
new file mode 100644
index 000000000..1cc898124
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/abstract-and-superv2.ecore
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="pak"
+ nsPrefix="pak">
+ <eClassifiers xsi:type="ecore:EClass" name="SomeClass"/>
+ <eClassifiers xsi:type="ecore:EClass" name="Master"/>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norename.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norename.ecore
new file mode 100644
index 000000000..8f8235ede
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norename.ecore
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="testPackage" nsURI="testPackageURI" nsPrefix="testPackagePrefix">
+ <eClassifiers xsi:type="ecore:EClass" name="ExistsInBoth"/>
+ <eClassifiers xsi:type="ecore:EClass" name="OnlyInDocument"/>
+ <eSubpackages name="sub" nsURI="sub" nsPrefix="sub"/>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norenamev2.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norenamev2.ecore
new file mode 100644
index 000000000..23bdf10ed
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/add-remove-norenamev2.ecore
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="testPackage" nsURI="testPackageURI" nsPrefix="testPackagePrefix">
+ <eClassifiers xsi:type="ecore:EClass" name="ExistsInBoth"/>
+ <eSubpackages name="sub" nsURI="sub" nsPrefix="sub">
+ <eClassifiers xsi:type="ecore:EClass" name="OnlyInWorkingCopy"/>
+ </eSubpackages>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-delete.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-delete.ecore
new file mode 100644
index 000000000..d4e1d1c55
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-delete.ecore
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="testPackage" nsURI="testPackageURI" nsPrefix="testPackagePrefix">
+ <eClassifiers xsi:type="ecore:EClass" name="A">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="a1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="a2" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-deletev2.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-deletev2.ecore
new file mode 100644
index 000000000..e47f80058
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/feature-update-deletev2.ecore
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="testPackage" nsURI="testPackageURI" nsPrefix="testPackagePrefix">
+ <eClassifiers xsi:type="ecore:EClass" name="A">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="a1" lowerBound="1" upperBound="-1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="a2" lowerBound="1" upperBound="4"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="a3" upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-delete.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-delete.ecore
new file mode 100644
index 000000000..7d31bd753
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-delete.ecore
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ name="p1" nsURI="p1" nsPrefix="p1">
+ <eSubpackages name="p2" nsURI="p2" nsPrefix="p2">
+ <eSubpackages name="subPackage" nsURI="subPackage" nsPrefix="subPackage"/>
+ </eSubpackages>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-deletev2.ecore b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-deletev2.ecore
new file mode 100644
index 000000000..d79390dcd
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/data/distance/package-add-deletev2.ecore
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ name="p1" nsURI="p1" nsPrefix="p1">
+ <eSubpackages name="p2" nsURI="p2" nsPrefix="p2"/>
+ <eSubpackages name="another" nsURI="another" nsPrefix="another"/>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EditionDistance.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EditionDistance.java
index fbfab18c1..577552c16 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EditionDistance.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EditionDistance.java
@@ -20,7 +20,6 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
-import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.CompareFactory;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.DifferenceKind;
@@ -75,6 +74,11 @@ public class EditionDistance implements DistanceFunction {
private Set<EStructuralFeature> toBeIgnored;
/**
+ * The instance used to compare location of EObjects.
+ */
+ private URIDistance uriDistance = new URIDistance();
+
+ /**
* The equality helper used to retrieve the URIs through its cache and to instanciate a specific diff
* engine.
*/
@@ -356,13 +360,9 @@ public class EditionDistance implements DistanceFunction {
Match fakeMatch = CompareFactory.eINSTANCE.createMatch();
fakeMatch.setLeft(a);
fakeMatch.setRight(b);
- URI aLocation = helper.getURI(a);
- URI bLocation = helper.getURI(b);
int changes = 0;
- if (!aLocation.fragment().equals(bLocation.fragment())) {
- int dist = new URIDistance().proximity(aLocation.fragment(), bLocation.fragment());
- changes += dist * locationChangeCoef;
- }
+ int dist = uriDistance.proximity(a, b);
+ changes += dist * locationChangeCoef;
if (changes <= maxDistance) {
checkForDifferences(fakeMatch);
changes += getCounter().getComputedDistance();
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/URIDistance.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/URIDistance.java
index f75eae524..7e0a29a6b 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/URIDistance.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/URIDistance.java
@@ -10,11 +10,24 @@
*******************************************************************************/
package org.eclipse.emf.compare.match.eobject;
+import com.google.common.base.Function;
import com.google.common.base.Splitter;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Lists;
import java.util.List;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+
/**
* This class is able to measure similarity between "URI like" strings, basically strings separated by "/".
* This is mainly intended to be used with EMF's fragments.
@@ -23,6 +36,88 @@ import java.util.List;
*/
public class URIDistance {
/**
+ * Function computing the location of each EObject.
+ */
+ private EObjectToLocation eObjToLoc = new EObjectToLocation();
+
+ /**
+ * This is the function that will be used by our {@link #uriCache} to compute its values.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+ private static class EObjectToLocation implements Function<EObject, List<String>> {
+ /**
+ * A computing cache for the locations.
+ */
+ private Cache<EObject, List<String>> locationCache = CacheBuilder.newBuilder().maximumSize(1000)
+ .build(CacheLoader.from(this));
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.common.base.Function#apply(java.lang.Object)
+ */
+ public List<String> apply(EObject input) {
+ if (input == null) {
+ return null;
+ }
+ EObject cur = input;
+ EObject container = input.eContainer();
+ Builder<String> builder = ImmutableList.builder();
+ if (container != null) {
+ builder.addAll(locationCache.getUnchecked(container));
+ EStructuralFeature feat = cur.eContainingFeature();
+ if (feat != null) {
+ if (feat instanceof EAttribute) {
+ featureMapLocation(builder, cur, container, feat);
+ } else {
+ if (feat.isMany()) {
+ EList<?> eList = (EList<?>)container.eGet(feat, false);
+ int index = eList.indexOf(cur);
+ builder.add(feat.getName());
+ builder.add(Integer.valueOf(index).toString());
+ } else {
+ builder.add(feat.getName());
+ builder.add("0");
+ }
+ }
+
+ }
+ } else {
+ builder.add("0");
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Update the builder with location hints for a feature map.
+ *
+ * @param builder
+ * the list builder to update.
+ * @param cur
+ * the current object.
+ * @param container
+ * the current object container.
+ * @param feat
+ * the containing feature of the current object.
+ */
+ protected void featureMapLocation(Builder<String> builder, EObject cur, EObject container,
+ EStructuralFeature feat) {
+ FeatureMap featureMap = (FeatureMap)container.eGet(feat, false);
+ for (int i = 0, size = featureMap.size(); i < size; ++i) {
+ if (featureMap.getValue(i) == cur) {
+ EStructuralFeature entryFeature = featureMap.getEStructuralFeature(i);
+ if (entryFeature instanceof EReference && ((EReference)entryFeature).isContainment()) {
+ builder.add(feat.getName());
+ builder.add(Integer.valueOf(i).toString());
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Return a metric result URI similarities. It compares 2 strings splitting those by "/" and return an int
* representing the level of similarity. 0 - they are exactly the same to 10 - they are completely
* different. "adding a fragment", "removing a fragment".
@@ -37,6 +132,21 @@ public class URIDistance {
Splitter splitter = Splitter.on('/').trimResults().omitEmptyStrings();
List<String> fragments1 = Lists.newArrayList(splitter.split(str1));
List<String> fragments2 = Lists.newArrayList(splitter.split(str2));
+ return proximity(fragments1, fragments2);
+ }
+
+ /**
+ * Return a metric result URI similarities. It compares 2 list of fragments and return an int representing
+ * the level of similarity. 0 - they are exactly the same to 10 - they are completely different.
+ * "adding a fragment", "removing a fragment".
+ *
+ * @param fragments1
+ * First list of fragments to compare.
+ * @param fragments2
+ * Second list of fragments to compare.
+ * @return The number of changes to transform one uri to another one.
+ */
+ public int proximity(List<String> fragments1, List<String> fragments2) {
if (fragments1.size() == 0 && fragments2.size() == 0) {
return 0;
}
@@ -56,4 +166,21 @@ public class URIDistance {
return 10 - (int)similarity;
}
+ /**
+ * Return a metric result location similarities. A location might be seen as an URI except it does not
+ * depend on the referencing scheme of EObjects related to a given resource (with intrinsic IDs, with
+ * eKeys..). It the location of 2 EObjects and return an int representing the level of similarity. 0 -
+ * they are exactly the same to 10 - they are completely different. "adding a fragment",
+ * "removing a fragment".
+ *
+ * @param a
+ * First of the two {@link EObject}s to compare.
+ * @param b
+ * Second of the two {@link EObject}s to compare.
+ * @return The number of changes to transform one uri to another one.
+ */
+ public int proximity(EObject a, EObject b) {
+ return proximity(eObjToLoc.apply(a), eObjToLoc.apply(b));
+ }
+
}

Back to the top