Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Goubet2013-02-26 16:05:51 +0000
committerLaurent Goubet2013-02-26 16:05:51 +0000
commit2941cee33950136e7a745efe84c2eab634745e39 (patch)
tree2c81b542d60323a63befdebc53995569fe1f82b9
parent9295242a662cf57f02e2cf3d5eb005a7b22b1d88 (diff)
parent0cd6310be837f5c0963eaaadf07d01574bf21964 (diff)
downloadorg.eclipse.emf.compare-2941cee33950136e7a745efe84c2eab634745e39.tar.gz
org.eclipse.emf.compare-2941cee33950136e7a745efe84c2eab634745e39.tar.xz
org.eclipse.emf.compare-2941cee33950136e7a745efe84c2eab634745e39.zip
Merge branch 'master' into logical_experimentation
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/edgechanges/EdgechangesTest.java213
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/nodechanges/NodechangesTest.java609
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java5
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java16
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DistanceAxiomsTests.java19
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java12
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/DefaultMatchEngine.java19
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ByTypeIndex.java24
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EObjectIndex.java9
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EUriFragmentFunction.java190
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EditionDistance.java298
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IEObjectMatcher.java14
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IdentifierEObjectMatcher.java14
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityEObjectMatcher.java216
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityIndex.java181
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityMatchStats.java129
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ReflectiveWeightProvider.java70
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ScopeQuery.java30
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/URIDistance.java57
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/WeightProvider.java19
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/EqualityHelper.java6
21 files changed, 1609 insertions, 541 deletions
diff --git a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/edgechanges/EdgechangesTest.java b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/edgechanges/EdgechangesTest.java
index 778188a7d..98f6e63dd 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/edgechanges/EdgechangesTest.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/edgechanges/EdgechangesTest.java
@@ -44,94 +44,110 @@ public class EdgechangesTest extends AbstractTest {
final Resource left = input.getA1Left();
final Resource right = input.getA1Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(), right.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(),
+ right.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 2 differences
assertSame(Integer.valueOf(2), Integer.valueOf(differences.size()));
-
- final Diff attributeChange = Iterators.find(differences.iterator(), and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
-
+
+ final Diff attributeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
+
assertNotNull(attributeChange);
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(1), edgeChange.getRefinedBy().size());
assertTrue(edgeChange.getRefinedBy().contains(attributeChange));
}
-
+
@Test
public void testA11UseCase() throws IOException {
final Resource left = input.getA1Left();
final Resource right = input.getA1Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(), left.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(),
+ left.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 60 differences
assertSame(Integer.valueOf(2), Integer.valueOf(differences.size()));
-
- final Diff attributeChange = Iterators.find(differences.iterator(), and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
-
+
+ final Diff attributeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
+
assertNotNull(attributeChange);
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(1), edgeChange.getRefinedBy().size());
- assertTrue(edgeChange.getRefinedBy().contains(attributeChange));
+ assertTrue(edgeChange.getRefinedBy().contains(attributeChange));
}
-
+
@Test
@Ignore
public void testA20UseCase() throws IOException {
final Resource left = input.getA2Left();
final Resource right = input.getA2Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(), right.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(),
+ right.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
-
+
// We should have no less and no more than 4 differences
assertSame(Integer.valueOf(4), Integer.valueOf(differences.size()));
-
- Collection<Diff> diffs = Collections2.filter(differences, and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
-
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
-
+
+ Collection<Diff> diffs = Collections2.filter(differences,
+ and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
+
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
+
assertTrue(diffs.size() == 3);
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(3), edgeChange.getRefinedBy().size());
assertTrue(edgeChange.getRefinedBy().containsAll(diffs));
-
+
}
-
+
@Test
@Ignore
public void testA21UseCase() throws IOException {
final Resource left = input.getA2Left();
final Resource right = input.getA2Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(), left.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(),
+ left.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 4 differences
assertSame(Integer.valueOf(4), Integer.valueOf(differences.size()));
-
- Collection<Diff> diffs = Collections2.filter(differences, and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
-
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
-
+
+ Collection<Diff> diffs = Collections2.filter(differences,
+ and(instanceOf(AttributeChange.class), ofKind(DifferenceKind.CHANGE)));
+
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
+
assertTrue(diffs.size() == 3);
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(3), edgeChange.getRefinedBy().size());
assertTrue(edgeChange.getRefinedBy().containsAll(diffs));
}
@@ -141,121 +157,138 @@ public class EdgechangesTest extends AbstractTest {
final Resource left = input.getA3Left();
final Resource right = input.getA3Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(), right.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(),
+ right.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
-
+
// We should have no less and no more than 2 differences
assertSame(Integer.valueOf(2), Integer.valueOf(differences.size()));
-
- final Diff attributeChange = Iterators.find(differences.iterator(), and(instanceOf(ReferenceChange.class), ofKind(DifferenceKind.ADD)));
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
-
+
+ final Diff attributeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(ReferenceChange.class), ofKind(DifferenceKind.ADD)));
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
+
assertNotNull(attributeChange);
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(1), edgeChange.getRefinedBy().size());
- assertTrue(edgeChange.getRefinedBy().contains(attributeChange));
-
+ assertTrue(edgeChange.getRefinedBy().contains(attributeChange));
+
}
-
+
@Test
public void testA31UseCase() throws IOException {
final Resource left = input.getA3Left();
final Resource right = input.getA3Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(), left.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(),
+ left.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 2 differences
assertSame(Integer.valueOf(2), Integer.valueOf(differences.size()));
-
- final Diff attributeChange = Iterators.find(differences.iterator(), and(instanceOf(ReferenceChange.class), ofKind(DifferenceKind.DELETE)));
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
-
+
+ final Diff attributeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(ReferenceChange.class), ofKind(DifferenceKind.DELETE)));
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.MOVE)));
+
assertNotNull(attributeChange);
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(1), edgeChange.getRefinedBy().size());
- assertTrue(edgeChange.getRefinedBy().contains(attributeChange));
+ assertTrue(edgeChange.getRefinedBy().contains(attributeChange));
}
-
+
@Test
@Ignore
public void testA40UseCase() throws IOException {
final Resource left = input.getA4Left();
final Resource right = input.getA4Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(), right.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(),
+ right.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
-
+
// We should have no less and no more than 13 differences
assertSame(Integer.valueOf(13), Integer.valueOf(differences.size()));
-
+
Collection<Diff> diffs = Collections2.filter(differences, instanceOf(ReferenceChange.class));
Diff addEdge = Iterators.find(differences.iterator(), and(valueIsEdge, ofKind(DifferenceKind.ADD)));
assertNotNull(addEdge);
-
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.ADD)));
+
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.ADD)));
assertSame(Integer.valueOf(12), diffs.size());
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(11), edgeChange.getRefinedBy().size());
- assertFalse(edgeChange.getRefinedBy().contains(addEdge));
-
+ assertFalse(edgeChange.getRefinedBy().contains(addEdge));
+
}
-
+
@Test
public void testA41UseCase() throws IOException {
final Resource left = input.getA4Left();
final Resource right = input.getA4Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(), left.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(),
+ left.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 13 differences
assertSame(Integer.valueOf(13), Integer.valueOf(differences.size()));
-
+
Collection<Diff> diffs = Collections2.filter(differences, instanceOf(ReferenceChange.class));
-
- final Diff edgeChange = Iterators.find(differences.iterator(), and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.DELETE)));
-
+
+ final Diff edgeChange = Iterators.find(differences.iterator(),
+ and(instanceOf(EdgeChange.class), ofKind(DifferenceKind.DELETE)));
+
assertSame(Integer.valueOf(12), diffs.size());
assertNotNull(edgeChange);
-
+
assertSame(Integer.valueOf(1), edgeChange.getRefinedBy().size());
- Diff deleteEdge = Iterators.find(differences.iterator(), and(valueIsEdge, ofKind(DifferenceKind.DELETE)));
+ Diff deleteEdge = Iterators.find(differences.iterator(),
+ and(valueIsEdge, ofKind(DifferenceKind.DELETE)));
assertTrue(edgeChange.getRefinedBy().contains(deleteEdge));
}
-
+
@Override
protected DiagramInputData getInput() {
return input;
}
-
+
final Predicate<Diff> valueIsEdge = new Predicate<Diff>() {
public boolean apply(Diff input) {
- return input instanceof ReferenceChange && ((ReferenceChange)input).getValue() instanceof Edge && ((ReferenceChange)input).getReference().isContainment();
+ return input instanceof ReferenceChange && ((ReferenceChange)input).getValue() instanceof Edge
+ && ((ReferenceChange)input).getReference().isContainment();
}
};
-
+
private static Predicate<? super Diff> valueUnder(final Diff container) {
return new Predicate<Diff>() {
- public boolean apply(Diff input) {
+ public boolean apply(Diff input) {
if (input instanceof ReferenceChange) {
- final ReferenceChange diff = (ReferenceChange) input;
+ final ReferenceChange diff = (ReferenceChange)input;
if (diff.getReference().isContainment()) {
return diff.getValue() == MatchUtil.getValue(container);
} else {
- return MatchUtil.getContainer(diff.getMatch().getComparison(), diff) == MatchUtil.getValue(container);
+ return MatchUtil.getContainer(diff.getMatch().getComparison(), diff) == MatchUtil
+ .getValue(container);
}
}
return false;
@@ -270,5 +303,5 @@ public class EdgechangesTest extends AbstractTest {
}
};
}
-
+
}
diff --git a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/nodechanges/NodechangesTest.java b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/nodechanges/NodechangesTest.java
index ac59cb22e..09ad88565 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/nodechanges/NodechangesTest.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/nodechanges/NodechangesTest.java
@@ -58,83 +58,161 @@ public class NodechangesTest extends AbstractTest {
final Resource left = input.getA1Left();
final Resource right = input.getA1Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(), right.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(),
+ right.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 57 differences
assertSame(Integer.valueOf(57), Integer.valueOf(differences.size()));
-
+
final Diff addEPackage = Iterators.find(differences.iterator(), added("tc1.EPackage0"));
-
- final Diff addEPackageView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1002", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEPackage).getValue())));
- final Diff addNodeInEPackageView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4006", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5003", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addMultiDiagramLinkStyleInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(MultiDiagramLinkStyle.class)));
- final Diff addBoundsInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(Bounds.class)));
- final Diff addRefElementInEPackageView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEPackage).getValue()), onFeature("element")));
-
+
+ final Diff addEPackageView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1002", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEPackage).getValue())));
+ final Diff addNodeInEPackageView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4006", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5003", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addMultiDiagramLinkStyleInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(MultiDiagramLinkStyle.class)));
+ final Diff addBoundsInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(Bounds.class)));
+ final Diff addRefElementInEPackageView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEPackage).getValue()), onFeature("element")));
+
final Diff addEClass = Iterators.find(differences.iterator(), added("tc1.EClass0"));
-
- final Diff addEClassView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1001", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEClass).getValue())));
- final Diff addNodeInEClassView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4001", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5001", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5002", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEClassView = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEClassView = Iterators.find(differences.iterator(), valueUnder(addEClassView));
- final Diff addRefElementInEClassView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEClass).getValue()), onFeature("element")));
- final Diff addBoundsInEClassView = Iterators.find(differences.iterator(), and(valueUnder(addEClassView), valueIsInstanceof(Bounds.class)));
-
+
+ final Diff addEClassView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1001", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEClass).getValue())));
+ final Diff addNodeInEClassView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4001", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5001", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5002", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEClassView = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEClassView = Iterators.find(differences.iterator(),
+ valueUnder(addEClassView));
+ final Diff addRefElementInEClassView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEClass).getValue()), onFeature("element")));
+ final Diff addBoundsInEClassView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEClassView), valueIsInstanceof(Bounds.class)));
+
final Diff addEDataType = Iterators.find(differences.iterator(), added("tc1.EDataType0"));
-
- final Diff addEDataTypeView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1004", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEDataType).getValue())));
- final Diff addNodeInEDataTypeView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4008", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEDataTypeView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4009", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addShapeStyleInEDataTypeView = Iterators.find(differences.iterator(), and(valueUnder(addEDataTypeView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addRefElementInEDataTypeView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEDataType).getValue()), onFeature("element")));
- final Diff addBoundsInEDataTypeView = Iterators.find(differences.iterator(), and(valueUnder(addEDataTypeView), valueIsInstanceof(Bounds.class)));
-
+
+ final Diff addEDataTypeView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1004", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEDataType).getValue())));
+ final Diff addNodeInEDataTypeView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4008", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEDataTypeView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4009", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addShapeStyleInEDataTypeView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEDataTypeView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addRefElementInEDataTypeView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEDataType).getValue()), onFeature("element")));
+ final Diff addBoundsInEDataTypeView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEDataTypeView), valueIsInstanceof(Bounds.class)));
+
final Diff addEEnum = Iterators.find(differences.iterator(), added("tc1.EEnum0"));
-
- final Diff addEEnumView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1005", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEEnum).getValue())));
- final Diff addNodeInEEnumView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4010", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5008", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEEnumView = Iterators.find(differences.iterator(), and(valueUnder(addEEnumView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addRefElementInEEnumView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEEnum).getValue()), onFeature("element")));
- final Diff addBoundsInEEnumView = Iterators.find(differences.iterator(), and(valueUnder(addEEnumView), valueIsInstanceof(Bounds.class)));
-
- final Diff addEAnnotation = Iterators.find(differences.iterator(), addedToReference("tc1", "eAnnotations", "tc1.EAnnotation0", EcorePackage.Literals.EANNOTATION__SOURCE));
-
- final Diff addEAnnotationView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1003", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEAnnotation).getValue())));
- final Diff addNodeInEAnnotationView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4007", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5007", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEAnnotationView = Iterators.find(differences.iterator(), and(valueUnder(addEAnnotationView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addRefElementInEAnnotationView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEAnnotation).getValue()), onFeature("element")));
- final Diff addBoundsInEAnnotationView = Iterators.find(differences.iterator(), and(valueUnder(addEAnnotationView), valueIsInstanceof(Bounds.class)));
-
- assertSame(Integer.valueOf(5), count(differences, and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD))));
-
- final Diff addNodeEPackageExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD), refinedBy(addRefElementInEPackageView)));
- final Diff addNodeEClassExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD), refinedBy(addRefElementInEClassView)));
- final Diff addNodeEDataTypeExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD), refinedBy(addRefElementInEDataTypeView)));
- final Diff addNodeEENumExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD), refinedBy(addRefElementInEEnumView)));
- final Diff addNodeEAnnotationExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD), refinedBy(addRefElementInEAnnotationView)));
+
+ final Diff addEEnumView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1005", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEEnum).getValue())));
+ final Diff addNodeInEEnumView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4010", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5008", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEEnumView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEEnumView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addRefElementInEEnumView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEEnum).getValue()), onFeature("element")));
+ final Diff addBoundsInEEnumView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEEnumView), valueIsInstanceof(Bounds.class)));
+
+ final Diff addEAnnotation = Iterators.find(
+ differences.iterator(),
+ addedToReference("tc1", "eAnnotations", "tc1.EAnnotation0",
+ EcorePackage.Literals.EANNOTATION__SOURCE));
+
+ final Diff addEAnnotationView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1003", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEAnnotation).getValue())));
+ final Diff addNodeInEAnnotationView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4007", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5007", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEAnnotationView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEAnnotationView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addRefElementInEAnnotationView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEAnnotation).getValue()), onFeature("element")));
+ final Diff addBoundsInEAnnotationView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEAnnotationView), valueIsInstanceof(Bounds.class)));
+
+ assertSame(Integer.valueOf(5),
+ count(differences, and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD))));
+
+ final Diff addNodeEPackageExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD),
+ refinedBy(addRefElementInEPackageView)));
+ final Diff addNodeEClassExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD),
+ refinedBy(addRefElementInEClassView)));
+ final Diff addNodeEDataTypeExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD),
+ refinedBy(addRefElementInEDataTypeView)));
+ final Diff addNodeEENumExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD),
+ refinedBy(addRefElementInEEnumView)));
+ final Diff addNodeEAnnotationExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD),
+ refinedBy(addRefElementInEAnnotationView)));
assertSame(Integer.valueOf(9), addNodeEPackageExtension.getRefinedBy().size());
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addNodeInEPackageView1));
@@ -146,7 +224,7 @@ public class NodechangesTest extends AbstractTest {
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addMultiDiagramLinkStyleInEPackageView));
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addBoundsInEPackageView));
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addRefElementInEPackageView));
-
+
assertSame(Integer.valueOf(12), addNodeEClassExtension.getRefinedBy().size());
assertTrue(addNodeEClassExtension.getRefinedBy().contains(addNodeInEClassView1));
assertTrue(addNodeEClassExtension.getRefinedBy().contains(addNodeInEClassView2));
@@ -167,7 +245,7 @@ public class NodechangesTest extends AbstractTest {
assertTrue(addNodeEDataTypeExtension.getRefinedBy().contains(addShapeStyleInEDataTypeView));
assertTrue(addNodeEDataTypeExtension.getRefinedBy().contains(addRefElementInEDataTypeView));
assertTrue(addNodeEDataTypeExtension.getRefinedBy().contains(addBoundsInEDataTypeView));
-
+
assertSame(Integer.valueOf(8), addNodeEENumExtension.getRefinedBy().size());
assertTrue(addNodeEENumExtension.getRefinedBy().contains(addNodeInEEnumView1));
assertTrue(addNodeEENumExtension.getRefinedBy().contains(addNodeInEEnumView2));
@@ -177,140 +255,217 @@ public class NodechangesTest extends AbstractTest {
assertTrue(addNodeEENumExtension.getRefinedBy().contains(addShapeStyleInEEnumView));
assertTrue(addNodeEENumExtension.getRefinedBy().contains(addRefElementInEEnumView));
assertTrue(addNodeEENumExtension.getRefinedBy().contains(addBoundsInEEnumView));
-
+
assertSame(Integer.valueOf(8), addNodeEAnnotationExtension.getRefinedBy().size());
assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addNodeInEAnnotationView1));
assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addNodeInEAnnotationView2));
- assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addDrawerStyleInNodeInEAnnotationView2));
- assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addSortingStyleInNodeInEAnnotationView2));
- assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addFilteringStyleInNodeInEAnnotationView2));
+ assertTrue(addNodeEAnnotationExtension.getRefinedBy()
+ .contains(addDrawerStyleInNodeInEAnnotationView2));
+ assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(
+ addSortingStyleInNodeInEAnnotationView2));
+ assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(
+ addFilteringStyleInNodeInEAnnotationView2));
assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addShapeStyleInEAnnotationView));
assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addRefElementInEAnnotationView));
assertTrue(addNodeEAnnotationExtension.getRefinedBy().contains(addBoundsInEAnnotationView));
-
+
// requires tests
assertSame(Integer.valueOf(0), addEPackageView.getRequires().size());
-
+
assertSame(Integer.valueOf(1), addNodeInEPackageView1.getRequires().size());
assertTrue(addNodeInEPackageView1.getRequires().contains(addEPackageView));
-
+
assertSame(Integer.valueOf(1), addNodeInEPackageView2.getRequires().size());
assertTrue(addNodeInEPackageView2.getRequires().contains(addEPackageView));
-
+
assertSame(Integer.valueOf(1), addDrawerStyleInNodeInEPackageView2.getRequires().size());
assertTrue(addDrawerStyleInNodeInEPackageView2.getRequires().contains(addNodeInEPackageView2));
-
+
assertSame(Integer.valueOf(1), addSortingStyleInNodeInEPackageView2.getRequires().size());
assertTrue(addSortingStyleInNodeInEPackageView2.getRequires().contains(addNodeInEPackageView2));
-
+
assertSame(Integer.valueOf(1), addFilteringStyleInNodeInEPackageView2.getRequires().size());
assertTrue(addFilteringStyleInNodeInEPackageView2.getRequires().contains(addNodeInEPackageView2));
-
+
assertSame(Integer.valueOf(1), addShapeStyleInEPackageView.getRequires().size());
assertTrue(addShapeStyleInEPackageView.getRequires().contains(addEPackageView));
-
+
assertSame(Integer.valueOf(1), addMultiDiagramLinkStyleInEPackageView.getRequires().size());
assertTrue(addMultiDiagramLinkStyleInEPackageView.getRequires().contains(addEPackageView));
-
+
assertSame(Integer.valueOf(1), addBoundsInEPackageView.getRequires().size());
assertTrue(addBoundsInEPackageView.getRequires().contains(addEPackageView));
-
+
assertSame(Integer.valueOf(2), addRefElementInEPackageView.getRequires().size());
assertTrue(addRefElementInEPackageView.getRequires().contains(addEPackage));
assertTrue(addRefElementInEPackageView.getRequires().contains(addEPackageView));
-
- assertFalse("No resource attachment changes expected", Iterators.filter(differences.iterator(), instanceOf(ResourceAttachmentChange.class)).hasNext());
+
+ assertFalse("No resource attachment changes expected",
+ Iterators.filter(differences.iterator(), instanceOf(ResourceAttachmentChange.class))
+ .hasNext());
}
-
+
@Test
public void testA11UseCase() throws IOException {
final Resource left = input.getA1Left();
final Resource right = input.getA1Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(), left.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(right.getResourceSet(),
+ left.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 57 differences
assertSame(Integer.valueOf(57), Integer.valueOf(differences.size()));
-
+
final Diff addEPackage = Iterators.find(differences.iterator(), removed("tc1.EPackage0"));
-
- final Diff addEPackageView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1002", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEPackage).getValue())));
- final Diff addNodeInEPackageView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4006", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5003", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addMultiDiagramLinkStyleInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(MultiDiagramLinkStyle.class)));
- final Diff addBoundsInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(Bounds.class)));
- final Diff addRefElementInEPackageView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEPackage).getValue()), onFeature("element")));
-
+
+ final Diff addEPackageView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1002", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEPackage).getValue())));
+ final Diff addNodeInEPackageView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4006", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5003", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addMultiDiagramLinkStyleInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(MultiDiagramLinkStyle.class)));
+ final Diff addBoundsInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(Bounds.class)));
+ final Diff addRefElementInEPackageView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEPackage).getValue()), onFeature("element")));
+
final Diff addEClass = Iterators.find(differences.iterator(), removed("tc1.EClass0"));
-
- final Diff addEClassView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1001", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEClass).getValue())));
- final Diff addNodeInEClassView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4001", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5001", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5002", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEClassView = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEClassView = Iterators.find(differences.iterator(), valueUnder(addEClassView));
- final Diff addRefElementInEClassView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEClass).getValue()), onFeature("element")));
- final Diff addBoundsInEClassView = Iterators.find(differences.iterator(), and(valueUnder(addEClassView), valueIsInstanceof(Bounds.class)));
-
+
+ final Diff addEClassView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1001", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEClass).getValue())));
+ final Diff addNodeInEClassView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4001", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5001", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5002", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEClassView = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEClassView = Iterators.find(differences.iterator(),
+ valueUnder(addEClassView));
+ final Diff addRefElementInEClassView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEClass).getValue()), onFeature("element")));
+ final Diff addBoundsInEClassView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEClassView), valueIsInstanceof(Bounds.class)));
+
final Diff addEDataType = Iterators.find(differences.iterator(), removed("tc1.EDataType0"));
-
- final Diff addEDataTypeView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1004", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEDataType).getValue())));
- final Diff addNodeInEDataTypeView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4008", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEDataTypeView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4009", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addShapeStyleInEDataTypeView = Iterators.find(differences.iterator(), and(valueUnder(addEDataTypeView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addRefElementInEDataTypeView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEDataType).getValue()), onFeature("element")));
- final Diff addBoundsInEDataTypeView = Iterators.find(differences.iterator(), and(valueUnder(addEDataTypeView), valueIsInstanceof(Bounds.class)));
-
+
+ final Diff addEDataTypeView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1004", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEDataType).getValue())));
+ final Diff addNodeInEDataTypeView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4008", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEDataTypeView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4009", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addShapeStyleInEDataTypeView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEDataTypeView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addRefElementInEDataTypeView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEDataType).getValue()), onFeature("element")));
+ final Diff addBoundsInEDataTypeView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEDataTypeView), valueIsInstanceof(Bounds.class)));
+
final Diff addEEnum = Iterators.find(differences.iterator(), removed("tc1.EEnum0"));
-
- final Diff addEEnumView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1005", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEEnum).getValue())));
- final Diff addNodeInEEnumView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4010", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5008", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEEnumView = Iterators.find(differences.iterator(), and(valueUnder(addEEnumView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addRefElementInEEnumView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEEnum).getValue()), onFeature("element")));
- final Diff addBoundsInEEnumView = Iterators.find(differences.iterator(), and(valueUnder(addEEnumView), valueIsInstanceof(Bounds.class)));
-
- final Diff addEAnnotation = Iterators.find(differences.iterator(), removedFromReference("tc1", "eAnnotations", "tc1.EAnnotation0", EcorePackage.Literals.EANNOTATION__SOURCE));
-
- final Diff addEAnnotationView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1003", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEAnnotation).getValue())));
- final Diff addNodeInEAnnotationView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4007", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5007", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEAnnotationView = Iterators.find(differences.iterator(), and(valueUnder(addEAnnotationView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addRefElementInEAnnotationView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEAnnotation).getValue()), onFeature("element")));
- final Diff addBoundsInEAnnotationView = Iterators.find(differences.iterator(), and(valueUnder(addEAnnotationView), valueIsInstanceof(Bounds.class)));
-
- assertSame(Integer.valueOf(5), count(differences, and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE))));
-
- final Diff addNodeEPackageExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEPackageView)));
- final Diff addNodeEClassExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEClassView)));
- final Diff addNodeEDataTypeExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEDataTypeView)));
- final Diff addNodeEENumExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEEnumView)));
- final Diff addNodeEAnnotationExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEAnnotationView)));
+
+ final Diff addEEnumView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1005", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEEnum).getValue())));
+ final Diff addNodeInEEnumView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4010", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5008", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEEnumView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEEnumView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEEnumView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEEnumView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addRefElementInEEnumView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEEnum).getValue()), onFeature("element")));
+ final Diff addBoundsInEEnumView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEEnumView), valueIsInstanceof(Bounds.class)));
+
+ final Diff addEAnnotation = Iterators.find(
+ differences.iterator(),
+ removedFromReference("tc1", "eAnnotations", "tc1.EAnnotation0",
+ EcorePackage.Literals.EANNOTATION__SOURCE));
+
+ final Diff addEAnnotationView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1003", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEAnnotation).getValue())));
+ final Diff addNodeInEAnnotationView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4007", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5007", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEAnnotationView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEAnnotationView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEAnnotationView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEAnnotationView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addRefElementInEAnnotationView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEAnnotation).getValue()), onFeature("element")));
+ final Diff addBoundsInEAnnotationView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEAnnotationView), valueIsInstanceof(Bounds.class)));
+
+ assertSame(Integer.valueOf(5),
+ count(differences, and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE))));
+
+ final Diff addNodeEPackageExtension = Iterators.find(differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEPackageView)));
+ final Diff addNodeEClassExtension = Iterators.find(differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEClassView)));
+ final Diff addNodeEDataTypeExtension = Iterators
+ .find(differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE),
+ refinedBy(addEDataTypeView)));
+ final Diff addNodeEENumExtension = Iterators.find(differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE), refinedBy(addEEnumView)));
+ final Diff addNodeEAnnotationExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.DELETE),
+ refinedBy(addEAnnotationView)));
assertSame(Integer.valueOf(1), addNodeEPackageExtension.getRefinedBy().size());
assertSame(Integer.valueOf(1), addNodeEClassExtension.getRefinedBy().size());
assertSame(Integer.valueOf(1), addNodeEDataTypeExtension.getRefinedBy().size());
assertSame(Integer.valueOf(1), addNodeEENumExtension.getRefinedBy().size());
assertSame(Integer.valueOf(1), addNodeEAnnotationExtension.getRefinedBy().size());
-
+
}
@Test
@@ -319,48 +474,84 @@ public class NodechangesTest extends AbstractTest {
final Resource left = input.getA3Left();
final Resource right = input.getA3Right();
- final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(), right.getResourceSet());
- final Comparison comparison = EMFCompare.builder().setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
-
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left.getResourceSet(),
+ right.getResourceSet());
+ final Comparison comparison = EMFCompare.builder()
+ .setPostProcessorRegistry(getPostProcessorRegistry()).build().compare(scope);
+
final List<Diff> differences = comparison.getDifferences();
// We should have no less and no more than 27 differences
assertSame(Integer.valueOf(27), Integer.valueOf(differences.size()));
-
+
final Diff addEPackage = Iterators.find(differences.iterator(), added("tc1.EPackage0"));
-
- final Diff addEPackageView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("1002", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEPackage).getValue())));
- final Diff addNodeInEPackageView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4006", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5003", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(ShapeStyle.class)));
- final Diff addMultiDiagramLinkStyleInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(MultiDiagramLinkStyle.class)));
- final Diff addBoundsInEPackageView = Iterators.find(differences.iterator(), and(valueUnder(addEPackageView), valueIsInstanceof(Bounds.class)));
- final Diff addRefElementInEPackageView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEPackage).getValue()), onFeature("element")));
-
+
+ final Diff addEPackageView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("1002", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEPackage).getValue())));
+ final Diff addNodeInEPackageView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4006", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5003", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEPackageView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEPackageView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(ShapeStyle.class)));
+ final Diff addMultiDiagramLinkStyleInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(MultiDiagramLinkStyle.class)));
+ final Diff addBoundsInEPackageView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEPackageView), valueIsInstanceof(Bounds.class)));
+ final Diff addRefElementInEPackageView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEPackage).getValue()), onFeature("element")));
+
final Diff addEClass = Iterators.find(differences.iterator(), added("tc1.EPackage0.EClass0"));
-
- final Diff addEClassView = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("2003", NotationPackage.Literals.VIEW__TYPE), elementIs(((ReferenceChange)addEClass).getValue())));
- final Diff addNodeInEClassView1 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("4002", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5004", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEClassView2 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView2), valueIsInstanceof(FilteringStyle.class)));
- final Diff addNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueIsView, valueNameMatches("5005", NotationPackage.Literals.VIEW__TYPE)));
- final Diff addDrawerStyleInNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(DrawerStyle.class)));
- final Diff addSortingStyleInNodeInEClassView3 = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(SortingStyle.class)));
- final Diff addFilteringStyleInNodeInEClassView = Iterators.find(differences.iterator(), and(valueUnder(addNodeInEClassView3), valueIsInstanceof(FilteringStyle.class)));
- final Diff addShapeStyleInEClassView = Iterators.find(differences.iterator(), valueUnder(addEClassView));
- final Diff addRefElementInEClassView = Iterators.find(differences.iterator(), and(valueIs(((ReferenceChange)addEClass).getValue()), onFeature("element")));
- final Diff addBoundsInEClassView = Iterators.find(differences.iterator(), and(valueUnder(addEClassView), valueIsInstanceof(Bounds.class)));
-
- assertSame(Integer.valueOf(2), count(differences, and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD))));
-
- final Diff addNodeEPackageExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD), refinedBy(addRefElementInEPackageView)));
- final Diff addNodeEClassExtension = Iterators.find(differences.iterator(), and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD), refinedBy(addRefElementInEClassView)));
-
+
+ final Diff addEClassView = Iterators.find(
+ differences.iterator(),
+ and(valueIsView, valueNameMatches("2003", NotationPackage.Literals.VIEW__TYPE),
+ elementIs(((ReferenceChange)addEClass).getValue())));
+ final Diff addNodeInEClassView1 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("4002", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5004", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEClassView2 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView2), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueIsView, valueNameMatches("5005", NotationPackage.Literals.VIEW__TYPE)));
+ final Diff addDrawerStyleInNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(DrawerStyle.class)));
+ final Diff addSortingStyleInNodeInEClassView3 = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(SortingStyle.class)));
+ final Diff addFilteringStyleInNodeInEClassView = Iterators.find(differences.iterator(),
+ and(valueUnder(addNodeInEClassView3), valueIsInstanceof(FilteringStyle.class)));
+ final Diff addShapeStyleInEClassView = Iterators.find(differences.iterator(),
+ valueUnder(addEClassView));
+ final Diff addRefElementInEClassView = Iterators.find(differences.iterator(),
+ and(valueIs(((ReferenceChange)addEClass).getValue()), onFeature("element")));
+ final Diff addBoundsInEClassView = Iterators.find(differences.iterator(),
+ and(valueUnder(addEClassView), valueIsInstanceof(Bounds.class)));
+
+ assertSame(Integer.valueOf(2),
+ count(differences, and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD))));
+
+ final Diff addNodeEPackageExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD),
+ refinedBy(addRefElementInEPackageView)));
+ final Diff addNodeEClassExtension = Iterators.find(
+ differences.iterator(),
+ and(instanceOf(NodeChange.class), ofKind(DifferenceKind.ADD),
+ refinedBy(addRefElementInEClassView)));
+
assertSame(Integer.valueOf(21), addNodeEPackageExtension.getRefinedBy().size());
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addNodeInEPackageView1));
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addNodeInEPackageView2));
@@ -383,7 +574,7 @@ public class NodechangesTest extends AbstractTest {
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addShapeStyleInEClassView));
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addRefElementInEClassView));
assertTrue(addNodeEPackageExtension.getRefinedBy().contains(addBoundsInEClassView));
-
+
assertSame(Integer.valueOf(12), addNodeEClassExtension.getRefinedBy().size());
assertTrue(addNodeEClassExtension.getRefinedBy().contains(addNodeInEClassView1));
assertTrue(addNodeEClassExtension.getRefinedBy().contains(addNodeInEClassView2));
@@ -397,27 +588,31 @@ public class NodechangesTest extends AbstractTest {
assertTrue(addNodeEClassExtension.getRefinedBy().contains(addShapeStyleInEClassView));
assertTrue(addNodeEClassExtension.getRefinedBy().contains(addRefElementInEClassView));
assertTrue(addNodeEClassExtension.getRefinedBy().contains(addBoundsInEClassView));
-
- assertFalse("No resource attachment changes expected", Iterators.filter(differences.iterator(), instanceOf(ResourceAttachmentChange.class)).hasNext());
+
+ assertFalse("No resource attachment changes expected",
+ Iterators.filter(differences.iterator(), instanceOf(ResourceAttachmentChange.class))
+ .hasNext());
}
-
+
@Override
protected DiagramInputData getInput() {
return input;
}
-
+
final Predicate<Diff> valueIsView = new Predicate<Diff>() {
public boolean apply(Diff input) {
- return input instanceof ReferenceChange && ((ReferenceChange)input).getValue() instanceof View && ((ReferenceChange)input).getReference().isContainment();
+ return input instanceof ReferenceChange && ((ReferenceChange)input).getValue() instanceof View
+ && ((ReferenceChange)input).getReference().isContainment();
}
};
-
+
private static Predicate<? super Diff> valueUnder(final Diff container) {
return new Predicate<Diff>() {
- public boolean apply(Diff input) {
+ public boolean apply(Diff input) {
if (input instanceof ReferenceChange) {
- final ReferenceChange diff = (ReferenceChange) input;
- return container instanceof ReferenceChange && diff.getValue().eContainer() == ((ReferenceChange)container).getValue();
+ final ReferenceChange diff = (ReferenceChange)input;
+ return container instanceof ReferenceChange
+ && diff.getValue().eContainer() == ((ReferenceChange)container).getValue();
}
return false;
}
@@ -431,7 +626,7 @@ public class NodechangesTest extends AbstractTest {
}
};
}
-
+
private static Predicate<? super Diff> valueIsInstanceof(final Class expectedValue) {
return new Predicate<Diff>() {
public boolean apply(Diff input) {
@@ -448,7 +643,7 @@ public class NodechangesTest extends AbstractTest {
}
};
}
-
+
private static Predicate<? super Diff> elementIs(final EObject expectedValue) {
return new Predicate<Diff>() {
public boolean apply(Diff input) {
@@ -461,5 +656,5 @@ public class NodechangesTest extends AbstractTest {
}
};
}
-
+
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java
index aacbef171..153907a4d 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.handler;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import java.util.Iterator;
@@ -132,10 +131,8 @@ public abstract class AbstractCompareHandler extends AbstractHandler {
originEObjects = Iterators.emptyIterator();
}
- final Iterable<Match> matches = getEObjectMatcher().createMatches(leftEObjects, rightEObjects,
- originEObjects);
+ getEObjectMatcher().createMatches(comparison, leftEObjects, rightEObjects, originEObjects);
- Iterables.addAll(rootMatch.getSubmatches(), matches);
}
}
}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java
index 588b8c798..a6bc4ab15 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java
@@ -32,6 +32,7 @@ import org.eclipse.emf.compare.tests.nodes.NodesFactory;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
/**
@@ -94,11 +95,16 @@ public class LCSPerformanceTest {
* additions to merge, accounting for as many LCS computations.
* </p>
* <p>
- * Note that this test should run in less than 30 seconds... However that is not true on our build
- * machine, so the timeout has been raised to 60s.
+ * Note that this test should run in less than 30 seconds... we give it a little leeway with a 40 seconds
+ * time out.
+ * </p>
+ * <p>
+ * Ignored for now : the build machine is much too slow and does not execute this even when left 60s to do
+ * so.
* </p>
*/
- @Test(timeout = 60000)
+ @Ignore
+ @Test(timeout = 40000)
public void copyLeftToRight() {
IComparisonScope scope = EMFCompare.createDefaultScope(left, right);
Comparison comparison = EMFCompare.builder().build().compare(scope);
@@ -117,7 +123,11 @@ public class LCSPerformanceTest {
* The real assertion here is that this should never take more than 3 seconds to execute : we're resetting
* all differences so there are only 100 "slow" ones : resetting deletions need the LCS computation.
* </p>
+ * <p>
+ * Ignored for now : the build machine is much too slow.
+ * </p>
*/
+ @Ignore
@Test(timeout = 3000)
public void copyRightToLeft() {
IComparisonScope scope = EMFCompare.createDefaultScope(left, right);
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DistanceAxiomsTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DistanceAxiomsTests.java
index 4aad69b54..a76565d2a 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DistanceAxiomsTests.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DistanceAxiomsTests.java
@@ -13,10 +13,10 @@ package org.eclipse.emf.compare.tests.fullcomparison;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
-import org.eclipse.emf.compare.match.DefaultMatchEngine;
+import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.match.eobject.EditionDistance;
import org.eclipse.emf.compare.match.eobject.ProximityEObjectMatcher.DistanceFunction;
import org.eclipse.emf.compare.tests.suite.AllTests;
@@ -46,9 +46,12 @@ public class DistanceAxiomsTests {
private int MAX_DISTANCE = Integer.MAX_VALUE;
+ private Comparison comparison;
+
@Before
public void setUp() throws Exception {
AllTests.fillEMFRegistries();
+ this.comparison = CompareFactory.eINSTANCE.createComparison();
this.meter = new EditionDistance();
}
@@ -58,8 +61,8 @@ public class DistanceAxiomsTests {
@Theory
public void symetry(EObject a, EObject b) {
Assume.assumeTrue(a.eClass() == b.eClass());
- int aTob = meter.distance(a, b);
- int bToa = meter.distance(b, a);
+ double aTob = meter.distance(comparison, a, b);
+ double bToa = meter.distance(comparison, b, a);
assertEquals(aTob, bToa);
}
@@ -69,15 +72,15 @@ public class DistanceAxiomsTests {
@Theory
public void separation(EObject a) {
- assertEquals(0, meter.distance(a, a));
+ assertEquals(0, meter.distance(comparison, a, a));
}
@Theory
public void triangularInequality(EObject x, EObject y, EObject z) {
Assume.assumeTrue(x.eClass() == y.eClass() && x.eClass() == z.eClass());
- int xToz = meter.distance(x, z);
- int xToy = meter.distance(x, y);
- int yToz = meter.distance(y, z);
+ double xToz = meter.distance(comparison, x, z);
+ double xToy = meter.distance(comparison, x, y);
+ double yToz = meter.distance(comparison, y, z);
assertTrue("Triangular inequality (x-z <= x-y + y-z ) failed (" + xToz + "<=" + xToy + " + " + yToz
+ ")for \nx:" + x.toString() + "\n|y:" + y.toString() + "\n|z:" + z.toString(), xToz <= xToy
+ yToz);
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java
index 6befb7146..0c8e82f8d 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.compare.internal.spec;
import static com.google.common.collect.Iterables.filter;
+import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -27,6 +28,7 @@ import java.util.Set;
import org.eclipse.emf.common.util.AbstractEList;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.ComparePackage;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.impl.ComparisonImpl;
@@ -125,9 +127,15 @@ public class ComparisonSpec extends ComparisonImpl {
matchCrossReferencer = new MatchCrossReferencer();
eAdapters().add(matchCrossReferencer);
}
- Iterable<Match> crossRefs = filter(getInverse(element, matchCrossReferencer), Match.class);
+ Iterable<EObject> crossRefs = filter(getInverse(element, matchCrossReferencer),
+ new Predicate<EObject>() {
- return Iterables.getFirst(crossRefs, null);
+ public boolean apply(EObject input) {
+ return input.eClass() == ComparePackage.eINSTANCE.getMatch();
+ }
+ });
+
+ return (Match)Iterables.getFirst(crossRefs, null);
}
/**
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/DefaultMatchEngine.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/DefaultMatchEngine.java
index c0507f11e..06b0fc84e 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/DefaultMatchEngine.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/DefaultMatchEngine.java
@@ -13,7 +13,6 @@ package org.eclipse.emf.compare.match;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
@@ -25,7 +24,6 @@ import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.CompareFactory;
import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.MatchResource;
import org.eclipse.emf.compare.match.eobject.EditionDistance;
import org.eclipse.emf.compare.match.eobject.IEObjectMatcher;
@@ -185,9 +183,7 @@ public class DefaultMatchEngine implements IMatchEngine {
final Iterator<? extends EObject> rightEObjects = Iterators.concat(rightIterators.iterator());
final Iterator<? extends EObject> originEObjects = Iterators.concat(originIterators.iterator());
- final Iterable<Match> matches = getEObjectMatcher().createMatches(leftEObjects, rightEObjects,
- originEObjects);
- Iterables.addAll(comparison.getMatches(), matches);
+ getEObjectMatcher().createMatches(comparison, leftEObjects, rightEObjects, originEObjects);
}
/**
@@ -270,15 +266,13 @@ public class DefaultMatchEngine implements IMatchEngine {
originEObjects = Iterators.emptyIterator();
}
- final Iterable<Match> matches = getEObjectMatcher().createMatches(leftEObjects, rightEObjects,
- originEObjects);
+ getEObjectMatcher().createMatches(comparison, leftEObjects, rightEObjects, originEObjects);
- Iterables.addAll(comparison.getMatches(), matches);
}
/**
* This will query the scope for the given {@link EObject}s' children, then delegate to an
- * {@link IEObjectMatcher} to compute the {@link Match}es.
+ * {@link IEObjectMatcher} to compute the Matches.
* <p>
* We expect at least the <code>left</code> and <code>right</code> EObjects not to be <code>null</code>.
* </p>
@@ -313,10 +307,7 @@ public class DefaultMatchEngine implements IMatchEngine {
originEObjects = Iterators.emptyIterator();
}
- final Iterable<Match> matches = getEObjectMatcher().createMatches(leftEObjects, rightEObjects,
- originEObjects);
-
- Iterables.addAll(comparison.getMatches(), matches);
+ getEObjectMatcher().createMatches(comparison, leftEObjects, rightEObjects, originEObjects);
}
/**
@@ -383,7 +374,7 @@ public class DefaultMatchEngine implements IMatchEngine {
*/
public static IEObjectMatcher createDefaultEObjectMatcher(UseIdentifiers useIDs) {
final IEObjectMatcher matcher;
- final EditionDistance editionDistance = EditionDistance.builder().build();
+ final EditionDistance editionDistance = new EditionDistance();
switch (useIDs) {
case NEVER:
matcher = new ProximityEObjectMatcher(editionDistance);
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ByTypeIndex.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ByTypeIndex.java
index 10b6a6764..a9114072d 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ByTypeIndex.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ByTypeIndex.java
@@ -14,13 +14,15 @@ import com.google.common.base.Function;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
-import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
+import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.match.eobject.ProximityEObjectMatcher.DistanceFunction;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
@@ -48,13 +50,15 @@ class ByTypeIndex implements EObjectIndex {
*
* @param meter
* the function passed when instantiating delegate indexes.
+ * @param scope
+ * an instance
*/
- public ByTypeIndex(ProximityEObjectMatcher.DistanceFunction meter) {
+ public ByTypeIndex(ProximityEObjectMatcher.DistanceFunction meter, final ScopeQuery scope) {
this.meter = meter;
this.allIndexes = CacheBuilder.newBuilder().build(
CacheLoader.from(new Function<String, EObjectIndex>() {
public EObjectIndex apply(String input) {
- return new ProximityIndex(ByTypeIndex.this.meter);
+ return new ProximityIndex(ByTypeIndex.this.meter, scope);
}
}));
}
@@ -64,12 +68,12 @@ class ByTypeIndex implements EObjectIndex {
*
* @see org.eclipse.emf.compare.match.eobject.EObjectIndex#getValuesStillThere(org.eclipse.emf.compare.match.eobject.EObjectIndex.Side)
*/
- public Collection<EObject> getValuesStillThere(Side side) {
- LinkedHashSet<EObject> values = new LinkedHashSet<EObject>();
+ public Iterable<EObject> getValuesStillThere(Side side) {
+ List<Iterable<EObject>> allLists = Lists.newArrayList();
for (EObjectIndex typeSpecificIndex : allIndexes.asMap().values()) {
- values.addAll(typeSpecificIndex.getValuesStillThere(side));
+ allLists.add(typeSpecificIndex.getValuesStillThere(side));
}
- return values;
+ return Iterables.concat(allLists);
}
/**
@@ -78,10 +82,10 @@ class ByTypeIndex implements EObjectIndex {
* @see org.eclipse.emf.compare.match.eobject.EObjectIndex#findClosests(org.eclipse.emf.ecore.EObject,
* org.eclipse.emf.compare.match.eobject.EObjectIndex.Side, int)
*/
- public Map<Side, EObject> findClosests(EObject obj, Side side) {
+ public Map<Side, EObject> findClosests(Comparison inProgress, EObject obj, Side side) {
try {
EObjectIndex typeSpecificIndex = allIndexes.get(eClassKey(obj));
- return typeSpecificIndex.findClosests(obj, side);
+ return typeSpecificIndex.findClosests(inProgress, obj, side);
} catch (ExecutionException e) {
return Collections.emptyMap();
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EObjectIndex.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EObjectIndex.java
index 636b2dfd6..59eaa63c1 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EObjectIndex.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EObjectIndex.java
@@ -10,9 +10,9 @@
*******************************************************************************/
package org.eclipse.emf.compare.match.eobject;
-import java.util.Collection;
import java.util.Map;
+import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.ecore.EObject;
/**
@@ -29,11 +29,14 @@ public interface EObjectIndex {
* the side we are looking for.
* @return the list of EObjects of a given side still available in the index.
*/
- Collection<EObject> getValuesStillThere(Side side);
+ Iterable<EObject> getValuesStillThere(Side side);
/**
* Return the closest EObjects found in other sides than the one given.
*
+ * @param inProgress
+ * the comparison currently being computed. It will not be changed directly but only queried to
+ * know if some element has already been matched or not.
* @param eObj
* the base EObject used to lookup similar ones.
* @param side
@@ -41,7 +44,7 @@ public interface EObjectIndex {
* @return a map of Side, EObjects, returning all the found objects (and the passed one) which are the
* closests.
*/
- Map<Side, EObject> findClosests(EObject eObj, Side side);
+ Map<Side, EObject> findClosests(Comparison inProgress, EObject eObj, Side side);
/**
* Remove an object from the index.
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EUriFragmentFunction.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EUriFragmentFunction.java
new file mode 100644
index 000000000..7a785dab5
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/EUriFragmentFunction.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * 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.eobject;
+
+import com.google.common.base.Function;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.ecore.util.EContentsEList;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * A function computing an URI Fragment. This implementation is based on
+ * org.eclipse.emf.ecore.impl.BasicEObjectImpl.eURIFragmentSegment(EStructuralFeature, EObject) no ID or
+ * specific code for a given EObject instance will be used, and that's on purpose, in the case of UML models
+ * for instance the specialization of the eURIFragment() method leads to a massive loss of performance for no
+ * added value in our current use case (matching references).
+ *
+ * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
+ */
+public class EUriFragmentFunction implements Function<EObject, String> {
+
+ /**
+ * {@inheritDoc}
+ */
+ public String apply(EObject input) {
+ EObject container = input.eContainer();
+ EStructuralFeature feat = input.eContainingFeature();
+ if (container instanceof BasicEObjectImpl) {
+ // String frag = ((BasicEObjectImpl)container).eURIFragmentSegment(feat, input);
+ return eURIFragmentSegment(container, feat, input);
+ }
+ return null;
+ }
+
+ // CHECKSTYLE:OFF
+ public String eURIFragmentSegment(EObject container, EStructuralFeature eStructuralFeature,
+ EObject eObject) {
+ if (eStructuralFeature == null) {
+ for (@SuppressWarnings("unchecked")
+ EContentsEList.FeatureIterator<EObject> crossReferences = (EContentsEList.FeatureIterator<EObject>)((InternalEList<?>)container
+ .eCrossReferences()).basicIterator(); crossReferences.hasNext();) {
+ EObject crossReference = crossReferences.next();
+ if (crossReference == eObject) {
+ eStructuralFeature = crossReferences.feature();
+ }
+ }
+ }
+
+ StringBuilder result = new StringBuilder();
+ result.append('@');
+ result.append(eStructuralFeature.getName());
+
+ if (eStructuralFeature instanceof EAttribute) {
+ FeatureMap featureMap = (FeatureMap)container.eGet(eStructuralFeature, false);
+ for (int i = 0, size = featureMap.size(); i < size; ++i) {
+ if (featureMap.getValue(i) == eObject) {
+ EStructuralFeature entryFeature = featureMap.getEStructuralFeature(i);
+ if (entryFeature instanceof EReference && ((EReference)entryFeature).isContainment()) {
+ result.append('.');
+ result.append(i);
+ return result.toString();
+ }
+ }
+ }
+ result.append(".-1");
+ } else if (eStructuralFeature.isMany()) {
+ EList<EAttribute> eKeys = ((EReference)eStructuralFeature).getEKeys();
+ if (eKeys.isEmpty()) {
+ EList<?> eList = (EList<?>)container.eGet(eStructuralFeature, false);
+ int index = eList.indexOf(eObject);
+ result.append('.');
+ result.append(index);
+ } else {
+ EAttribute[] eAttributes = (EAttribute[])((BasicEList<?>)eKeys).data();
+ result.append('[');
+ for (int i = 0, size = eAttributes.length; i < size; ++i) {
+ EAttribute eAttribute = eAttributes[i];
+ if (eAttribute == null) {
+ break;
+ } else {
+ if (i != 0) {
+ result.append(',');
+ }
+ result.append(eAttribute.getName());
+ result.append('=');
+ EDataType eDataType = eAttribute.getEAttributeType();
+ EFactory eFactory = eDataType.getEPackage().getEFactoryInstance();
+ if (eAttribute.isMany()) {
+ List<?> values = (List<?>)eObject.eGet(eAttribute);
+ result.append('[');
+ if (!values.isEmpty()) {
+ Iterator<?> j = values.iterator();
+ eEncodeValue(result, eFactory, eDataType, j.next());
+ while (j.hasNext()) {
+ result.append(',');
+ eEncodeValue(result, eFactory, eDataType, j.next());
+ }
+ }
+ result.append(']');
+ } else {
+ eEncodeValue(result, eFactory, eDataType, eObject.eGet(eAttribute));
+ }
+ }
+ }
+ result.append(']');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private void eEncodeValue(StringBuilder result, EFactory eFactory, EDataType eDataType, Object value) {
+ String stringValue = eFactory.convertToString(eDataType, value);
+ if (stringValue == null) {
+ result.append("null");
+ } else {
+ int length = stringValue.length();
+ result.ensureCapacity(result.length() + length + 2);
+ result.append('\'');
+ for (int i = 0; i < length; ++i) {
+ char character = stringValue.charAt(i);
+ if (character < ESCAPE.length) {
+ String escape = ESCAPE[character];
+ if (escape != null) {
+ result.append(escape);
+ continue;
+ }
+ }
+ result.append(character);
+ }
+ result.append('\'');
+ }
+ }
+
+ /**
+ * Returns the encoded value or the original, if no encoding was needed.
+ *
+ * @param value
+ * the value to be encoded.
+ * @return the encoded value or the original, if no encoding was needed.
+ */
+ private String eEncodeValue(String value) {
+ int length = value.length();
+ StringBuilder result = null;
+ for (int i = 0; i < length; ++i) {
+ char character = value.charAt(i);
+ if (character < ESCAPE.length) {
+ String escape = ESCAPE[character];
+ if (escape != null) {
+ if (result == null) {
+ result = new StringBuilder(length + 2);
+ result.append(value, 0, i);
+ }
+ result.append(escape);
+ continue;
+ }
+ }
+ if (result != null) {
+ result.append(character);
+ }
+ }
+ return result == null ? value : result.toString();
+ }
+
+ private final String[] ESCAPE = {"%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09",
+ "%0A", "%0B", "%0C", "%0D", "%0E", "%0F", "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",
+ "%18", "%19", "%1A", "%1B", "%1C", "%1D", "%1E", "%1F", "%20", null, "%22", "%23", null, "%25",
+ "%26", "%27", null, null, null, null, "%2C", null, null, "%2F", null, null, null, null, null,
+ null, null, null, null, null, "%3A", null, "%3C", null, "%3E", null, };
+}
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 1e7cc9935..8587631e5 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,6 +20,8 @@ import java.util.Iterator;
import java.util.Set;
import org.eclipse.emf.common.util.BasicMonitor;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.CompareFactory;
import org.eclipse.emf.compare.Comparison;
@@ -29,7 +31,7 @@ import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.diff.DefaultDiffEngine;
import org.eclipse.emf.compare.diff.FeatureFilter;
import org.eclipse.emf.compare.diff.IDiffProcessor;
-import org.eclipse.emf.compare.match.DefaultComparisonFactory;
+import org.eclipse.emf.compare.internal.spec.ComparisonSpec;
import org.eclipse.emf.compare.match.DefaultEqualityHelperFactory;
import org.eclipse.emf.compare.match.IEqualityHelperFactory;
import org.eclipse.emf.compare.match.eobject.ProximityEObjectMatcher.DistanceFunction;
@@ -41,6 +43,7 @@ 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;
import org.eclipse.emf.ecore.util.InternalEList;
/**
@@ -49,20 +52,6 @@ import org.eclipse.emf.ecore.util.InternalEList;
* @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
*/
public class EditionDistance implements DistanceFunction {
- /**
- * It's the percentage of similarity we consider as being the limit on a maximum potential distance of 1.
- */
- private static final double MAX_DIST_RATIO = 0.75d;
-
- /**
- * Weight coefficient of a change on a reference.
- */
- private int referenceChangeCoef = 3;
-
- /**
- * Weight coefficient of a change on an attribute.
- */
- private int attributeChangeCoef = 10;
/**
* Weight coefficient of a change of location (uri).
@@ -72,7 +61,7 @@ public class EditionDistance implements DistanceFunction {
/**
* Weight coefficient of a change of order within a reference.
*/
- private int orderChangeCoef = 2;
+ private int orderChangeCoef = 1;
/**
* The instance used to compare location of EObjects.
@@ -80,6 +69,14 @@ public class EditionDistance implements DistanceFunction {
private URIDistance uriDistance = new URIDistance();
/**
+ * a thresholds ratio discrete function per the number of features.
+ */
+ // CHECKSTYLE:OFF we know these are magic numbers, so be it, they happens to have the same value but there
+ // is no semantic.
+ private double[] thresholds = {0, 0.6, 0.6, 0.55, 0.465 };
+
+ // CHECKSTYLE:ON
+ /**
* The fake comparison is used to make the diff engine super class happy. We are reusing the same instance
* which we are updating because of the cost of adding even a single Match in it (and subsequent growing
* of list) which gets very significant considering how much we are calling this during a single
@@ -103,23 +100,62 @@ public class EditionDistance implements DistanceFunction {
return new EqualityHelper(cache) {
@Override
protected boolean matchingURIs(EObject object1, EObject object2) {
+ /*
+ * we might trying to compare children of the objects under scrutinity right now, it
+ * might happen if a containment reference is seen as "relevant" for the matching
+ * process. In those cases, we don't want to compare the whole uris and instead want
+ * to compare just the current fragment. This has very important performance
+ * implications.
+ */
+ if (object1.eContainer() != null && object2.eContainer() != null
+ && fakeComparison.getMatch(object1.eContainer()) != null) {
+ return uriDistance.retrieveFragment(object1).equals(
+ uriDistance.retrieveFragment(object2));
+ }
return uriDistance.proximity(object1, object2) == 0;
}
};
}
};
- this.fakeComparison = new DefaultComparisonFactory(fakeEqualityHelperFactory).createComparison();
+
+ this.fakeComparison = new ComparisonSpec() {
+
+ /*
+ * We did override this method to avoid the extra cost of maintaining a cross referencer for such
+ * a fake comparison.
+ */
+ @Override
+ public Match getMatch(EObject element) {
+ for (Match m : getMatches()) {
+ if (m.getLeft() == element || m.getRight() == element || m.getOrigin() == element) {
+ return m;
+ }
+ }
+ return null;
+ }
+
+ };
+ Match fakeMatch = CompareFactory.eINSTANCE.createMatch();
+ ((InternalEList<Match>)fakeComparison.getMatches()).addUnique(fakeMatch);
+
+ IEqualityHelper equalityHelper = fakeEqualityHelperFactory.createEqualityHelper();
+
+ fakeComparison.eAdapters().add(equalityHelper);
+ equalityHelper.setTarget(fakeComparison);
+
}
/**
* {@inheritDoc}
*/
- public int distance(EObject a, EObject b) {
- int maxDist = Math.max(getMaxDistance(a), getMaxDistance(b));
- int measuredDist = new CountingDiffEngine(maxDist, this.fakeComparison).measureDifferences(a, b);
- if (measuredDist >= maxDist) {
- return Integer.MAX_VALUE;
+ public double distance(Comparison inProgress, EObject a, EObject b) {
+ this.uriDistance.setComparison(inProgress);
+ double maxDist = Math.max(getThresholdAmount(a), getThresholdAmount(b));
+ double measuredDist = new CountingDiffEngine(maxDist, this.fakeComparison).measureDifferences(
+ inProgress, a, b);
+ if (measuredDist > maxDist) {
+ return Double.MAX_VALUE;
}
return measuredDist;
}
@@ -127,8 +163,8 @@ public class EditionDistance implements DistanceFunction {
/**
* {@inheritDoc}
*/
- public boolean areIdentic(EObject a, EObject b) {
- return new CountingDiffEngine(0, this.fakeComparison).measureDifferences(a, b) == 0;
+ public boolean areIdentic(Comparison inProgress, EObject a, EObject b) {
+ return new CountingDiffEngine(0, this.fakeComparison).measureDifferences(inProgress, a, b) == 0;
}
/**
@@ -182,32 +218,6 @@ public class EditionDistance implements DistanceFunction {
}
/**
- * Specify the weight of any change of attribute value between two instances.
- *
- * @param weight
- * the new weight.
- * @return the current builder instance.
- */
-
- public Builder attribute(int weight) {
- this.toBeBuilt.attributeChangeCoef = weight;
- return this;
- }
-
- /**
- * Specify the weight of any change of reference between two instances.
- *
- * @param weight
- * the new weight.
- * @return the current builder instance.
- */
-
- public Builder reference(int weight) {
- this.toBeBuilt.referenceChangeCoef = weight;
- return this;
- }
-
- /**
* Configure custom weight provider.
*
* @param provider
@@ -243,7 +253,7 @@ public class EditionDistance implements DistanceFunction {
/**
* The current distance.
*/
- private int distance;
+ private double distance;
/**
* {@inheritDoc}
@@ -258,7 +268,7 @@ public class EditionDistance implements DistanceFunction {
case ADD:
case DELETE:
case CHANGE:
- distance += weights.getWeight(reference) * referenceChangeCoef;
+ distance += weights.getWeight(reference);
break;
default:
break;
@@ -286,10 +296,9 @@ public class EditionDistance implements DistanceFunction {
case CHANGE:
if (aValue instanceof String && bValue instanceof String) {
distance += weights.getWeight(attribute)
- * (1 - DiffUtil.diceCoefficient((String)aValue, (String)bValue))
- * attributeChangeCoef;
+ * (1 - DiffUtil.diceCoefficient((String)aValue, (String)bValue));
} else {
- distance += weights.getWeight(attribute) * attributeChangeCoef;
+ distance += weights.getWeight(attribute);
}
break;
default:
@@ -318,7 +327,7 @@ public class EditionDistance implements DistanceFunction {
*
* @return the computed distance.
*/
- public int getComputedDistance() {
+ public double getComputedDistance() {
return distance;
}
@@ -338,7 +347,7 @@ public class EditionDistance implements DistanceFunction {
/**
* The maximum distance until which we just have to stop.
*/
- private int maxDistance;
+ private double maxDistance;
/** The comparison for which this engine will detect differences. */
private final Comparison comparison;
@@ -351,7 +360,7 @@ public class EditionDistance implements DistanceFunction {
* @param fakeComparison
* the comparison instance to use while measuring the differences between the two objects.
*/
- public CountingDiffEngine(int maxDistance, Comparison fakeComparison) {
+ public CountingDiffEngine(double maxDistance, Comparison fakeComparison) {
super(new CountingDiffProcessor());
this.maxDistance = maxDistance;
// will always return the same instance.
@@ -361,6 +370,13 @@ public class EditionDistance implements DistanceFunction {
}
@Override
+ protected void checkResourceAttachment(Match match, Monitor monitor) {
+ /*
+ * we really don't want to check that...
+ */
+ }
+
+ @Override
protected void computeDifferences(Match match, EAttribute attribute, boolean checkOrdering) {
if (getCounter().getComputedDistance() <= maxDistance) {
super.computeDifferences(match, attribute, checkOrdering);
@@ -377,18 +393,36 @@ public class EditionDistance implements DistanceFunction {
/**
* Measure the difference between two objects and return a distance value.
*
+ * @param comparisonInProgress
+ * the comparison which is currently being matched.
* @param a
* first object.
* @param b
* second object.
* @return the distance between them computed using the number of changes required to change a to b.
*/
- public int measureDifferences(EObject a, EObject b) {
+ public double measureDifferences(Comparison comparisonInProgress, EObject a, EObject b) {
Match fakeMatch = createOrUpdateFakeMatch(a, b);
getCounter().reset();
- int changes = 0;
- int dist = uriDistance.proximity(a, b);
- changes += dist * locationChangeCoef;
+ double changes = 0;
+ if (!haveSameContainer(comparisonInProgress, a, b)) {
+ changes += locationChangeCoef * weights.getParentWeight(a);
+ } else {
+ int aIndex = getContainmentIndex(a);
+ int bIndex = getContainmentIndex(b);
+ if (aIndex != bIndex) {
+ /*
+ * we just want to pick the same positioned object if two exactly similar objects are
+ * candidates in the same container.
+ */
+ changes += 1;
+ }
+
+ }
+ if (a.eContainingFeature() != b.eContainingFeature()) {
+ changes += Math.max(weights.getContainingFeatureWeight(a), weights
+ .getContainingFeatureWeight(b));
+ }
if (changes <= maxDistance) {
checkForDifferences(fakeMatch, new BasicMonitor());
changes += getCounter().getComputedDistance();
@@ -398,6 +432,108 @@ public class EditionDistance implements DistanceFunction {
}
/**
+ * return the position in which an Object is contained in its parent list.
+ *
+ * @param a
+ * any EObject
+ * @return the position in which an Object is contained in its parent list, 0 if there is no container
+ * or if the reference is single valued.
+ */
+ private int getContainmentIndex(EObject a) {
+ EStructuralFeature feat = a.eContainingFeature();
+ EObject container = a.eContainer();
+ int position = 0;
+ if (container != null) {
+ if (feat instanceof EAttribute) {
+ position = indexFromFeatureMap(a, feat, container);
+ } else if (feat != null) {
+ if (feat.isMany()) {
+ EList<?> eList = (EList<?>)container.eGet(feat, false);
+ position = eList.indexOf(a);
+ }
+ }
+ }
+ return position;
+ }
+
+ /**
+ * the position of the {@link EObject} a in its container featureMap.
+ *
+ * @param a
+ * the {@link EObject}.
+ * @param feat
+ * the containing feature.
+ * @param container
+ * the containing EObject.
+ * @return the position of the {@link EObject} a in its container featureMap.
+ */
+ private int indexFromFeatureMap(EObject a, EStructuralFeature feat, EObject container) {
+ FeatureMap featureMap = (FeatureMap)container.eGet(feat, false);
+ for (int i = 0, size = featureMap.size(); i < size; ++i) {
+ if (featureMap.getValue(i) == a) {
+ EStructuralFeature entryFeature = featureMap.getEStructuralFeature(i);
+ if (entryFeature instanceof EReference && ((EReference)entryFeature).isContainment()) {
+ return i;
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Check whether two {@link EObject} have the same containers or not.
+ *
+ * @param inProgress
+ * the comparison currently being matched.
+ * @param a
+ * any {@link EObject}
+ * @param b
+ * any other {@link EObject}
+ * @return true if they have the same container. If the containers have been matched their match will
+ * be used, on the contrary the URI will be indirectly use through the EqualityHelper.
+ */
+ private boolean haveSameContainer(Comparison inProgress, EObject a, EObject b) {
+ EObject aContainer = a.eContainer();
+ EObject bContainer = b.eContainer();
+ if ((aContainer == null && bContainer != null) || (aContainer != null && bContainer == null)) {
+ return false;
+ }
+ /*
+ * we consider two null containers as being the "same".
+ */
+ boolean matching = aContainer == null && bContainer == null;
+ Match mA = inProgress.getMatch(aContainer);
+ Match mB = inProgress.getMatch(bContainer);
+ if (!matching) {
+ if (mA == null && mB == null) {
+ /*
+ * The Objects have to be out of scope then.
+ */
+ matching = fakeComparison.getEqualityHelper().matchingValues(aContainer, bContainer);
+ } else {
+ matching = isReferencedByTheMatch(bContainer, mA)
+ || isReferencedByTheMatch(aContainer, mB);
+ }
+ }
+ return matching;
+ }
+
+ /**
+ * Return true if the given {@link EObject} is referenced by the left/right or origin match reference.
+ *
+ * @param eObj
+ * any {@link EObject}.
+ * @param match
+ * any Match.
+ * @return true if the given {@link EObject} is referenced by the left/right or origin match
+ * reference.
+ */
+ private boolean isReferencedByTheMatch(EObject eObj, Match match) {
+ return match != null
+ && (match.getRight() == eObj || match.getLeft() == eObj || match.getOrigin() == eObj);
+ }
+
+ /**
* Create a mock {@link Match} between the two given EObjects so that we can use the exposed
* {@link #checkForDifferences(Match, org.eclipse.emf.common.util.Monitor)} method to check for
* differences.
@@ -409,10 +545,6 @@ public class EditionDistance implements DistanceFunction {
* @return The created Match.
*/
private Match createOrUpdateFakeMatch(EObject a, EObject b) {
- if (!comparison.getMatches().iterator().hasNext()) {
- Match fakeMatch = CompareFactory.eINSTANCE.createMatch();
- ((InternalEList<Match>)comparison.getMatches()).addUnique(fakeMatch);
- }
Match fakeMatch = comparison.getMatches().get(0);
fakeMatch.setLeft(a);
fakeMatch.setRight(b);
@@ -456,7 +588,7 @@ public class EditionDistance implements DistanceFunction {
/**
* {@inheritDoc}
*/
- public int getMaxDistance(EObject eObj) {
+ public double getThresholdAmount(EObject eObj) {
Predicate<EStructuralFeature> featureFilter = new Predicate<EStructuralFeature>() {
@@ -471,19 +603,41 @@ public class EditionDistance implements DistanceFunction {
// Ecore so I'll try to gather as much as test data I can and add the corresponding test to be able to
// assess the quality of further changes.
int max = 0;
+ int nbFeatures = 0;
for (EReference feat : Iterables.filter(eObj.eClass().getEAllReferences(), featureFilter)) {
if (eObj.eIsSet(feat)) {
- max += weights.getWeight(feat) * referenceChangeCoef;
+ max += weights.getWeight(feat);
+ nbFeatures++;
}
}
for (EAttribute feat : Iterables.filter(eObj.eClass().getEAllAttributes(), featureFilter)) {
if (eObj.eIsSet(feat)) {
- max += weights.getWeight(feat) * attributeChangeCoef;
+ max += weights.getWeight(feat);
+ nbFeatures++;
}
}
- // 10 is the maximum distance for an URIDistance.
- max = max + locationChangeCoef * uriDistance.getUpperBoundDistance();
- return Double.valueOf(max * MAX_DIST_RATIO).intValue();
+ // max = max + (locationChangeCoef * weights.getParentWeight(eObj));
+ max = max + weights.getContainingFeatureWeight(eObj);
+
+ return max * getThresholdRatio(nbFeatures);
+ }
+
+ /**
+ * return a ratio to appli on the amount of maximum un-similarity amount depending on the number of
+ * features which are considered.
+ *
+ * @param nbFeatures
+ * the nb of features which should be considerd to compute the amount.
+ * @return a ratio to appli on the amount of maximum un-similarity amount depending on the number of
+ * features which are considered.
+ */
+ private double getThresholdRatio(int nbFeatures) {
+ if (nbFeatures >= thresholds.length) {
+ // CHECKSTYLE:OFF
+ return 0.465d;
+ // CHECKSTYLE:ON
+ }
+ return thresholds[nbFeatures];
}
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IEObjectMatcher.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IEObjectMatcher.java
index 4e3e4059e..2415875ef 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IEObjectMatcher.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IEObjectMatcher.java
@@ -12,7 +12,7 @@ package org.eclipse.emf.compare.match.eobject;
import java.util.Iterator;
-import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.ecore.EObject;
/**
@@ -35,11 +35,14 @@ public interface IEObjectMatcher {
/**
* This will be called by the match engine to determine matches between EObjects.
* <p>
- * The returned matches should include both matching and unmatchings EObjects (i.e. EObjects that can be
- * matched in all three lists, EObjects that cna be matched in only two of the three lists, and EObjects
- * that can only be found in one of the three.
+ * The implementation should update the given comparison object by adding the Matches it detect. These
+ * matches should include both matching and unmatchings EObjects (i.e. EObjects that can be matched in all
+ * three lists, EObjects that cna be matched in only two of the three lists, and EObjects that can only be
+ * found in one of the three.
* </p>
*
+ * @param comparison
+ * the comparison to update.
* @param leftEObjects
* An iterator over the EObjects that could be found in the left side.
* @param rightEObjects
@@ -47,8 +50,7 @@ public interface IEObjectMatcher {
* @param originEObjects
* And iterator over the EObject that may be considered ancestors of the couples that can be
* detected in the left and right sides.
- * @return The list of all detected matches. Should also include unmatching EObjects.
*/
- Iterable<Match> createMatches(Iterator<? extends EObject> leftEObjects,
+ void createMatches(Comparison comparison, Iterator<? extends EObject> leftEObjects,
Iterator<? extends EObject> rightEObjects, Iterator<? extends EObject> originEObjects);
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IdentifierEObjectMatcher.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IdentifierEObjectMatcher.java
index c05566bf4..f9ed31b2f 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IdentifierEObjectMatcher.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/IdentifierEObjectMatcher.java
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
@@ -97,11 +98,8 @@ public class IdentifierEObjectMatcher implements IEObjectMatcher {
/**
* {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.match.eobject.IEObjectMatcher#createMatches(java.util.Iterator,
- * java.util.Iterator, java.util.Iterator)
*/
- public Iterable<Match> createMatches(Iterator<? extends EObject> leftEObjects,
+ public void createMatches(Comparison comparison, Iterator<? extends EObject> leftEObjects,
Iterator<? extends EObject> rightEObjects, Iterator<? extends EObject> originEObjects) {
final List<EObject> leftEObjectsNoID = Lists.newArrayList();
final List<EObject> rightEObjectsNoID = Lists.newArrayList();
@@ -110,9 +108,11 @@ public class IdentifierEObjectMatcher implements IEObjectMatcher {
final Set<Match> matches = matchPerId(leftEObjects, rightEObjects, originEObjects, leftEObjectsNoID,
rightEObjectsNoID, originEObjectsNoID);
+ Iterables.addAll(comparison.getMatches(), matches);
if (delegate.isPresent()) {
- Iterables.addAll(matches, delegate.get().createMatches(leftEObjectsNoID.iterator(),
- rightEObjectsNoID.iterator(), originEObjectsNoID.iterator()));
+
+ delegate.get().createMatches(comparison, leftEObjectsNoID.iterator(),
+ rightEObjectsNoID.iterator(), originEObjectsNoID.iterator());
} else {
for (EObject eObject : leftEObjectsNoID) {
Match match = CompareFactory.eINSTANCE.createMatch();
@@ -132,8 +132,6 @@ public class IdentifierEObjectMatcher implements IEObjectMatcher {
}
}
-
- return matches;
}
/**
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityEObjectMatcher.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityEObjectMatcher.java
index ca097303e..3b86c19dc 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityEObjectMatcher.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityEObjectMatcher.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.emf.compare.match.eobject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -18,7 +20,10 @@ import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.BasicMonitor;
+import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.match.eobject.EObjectIndex.Side;
import org.eclipse.emf.ecore.EObject;
@@ -39,7 +44,7 @@ import org.eclipse.emf.ecore.EObject;
*
* @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
*/
-public class ProximityEObjectMatcher implements IEObjectMatcher {
+public class ProximityEObjectMatcher implements IEObjectMatcher, ScopeQuery {
/**
* The index which keep the EObjects.
@@ -47,14 +52,9 @@ public class ProximityEObjectMatcher implements IEObjectMatcher {
private EObjectIndex index;
/**
- * The list of matches found.
+ * Keeps track of which side was the EObject from.
*/
- private List<Match> matches = Lists.newArrayList();
-
- /**
- * A map cross referencing the eObject to their match.
- */
- private Map<EObject, Match> eObjectsToMatch = Maps.newHashMap();
+ private Map<EObject, Side> eObjectsToSide = Maps.newHashMap();
/**
* Create the matcher using the given distance function.
@@ -63,88 +63,166 @@ public class ProximityEObjectMatcher implements IEObjectMatcher {
* a function to measure the distance between two {@link EObject}s.
*/
public ProximityEObjectMatcher(DistanceFunction meter) {
- this.index = new ByTypeIndex(meter);
+ this.index = new ByTypeIndex(meter, this);
}
/**
* {@inheritDoc}
*/
- public Iterable<Match> createMatches(Iterator<? extends EObject> leftEObjects,
+ public void createMatches(Comparison comparison, Iterator<? extends EObject> leftEObjects,
Iterator<? extends EObject> rightEObjects, Iterator<? extends EObject> originEObjects) {
+ // TODO use the monitor we have been passed on as soon as we have one.
+ Monitor monitor = new BasicMonitor();
+ monitor.beginTask("indexing objects", 1);
+ int nbElements = 0;
/*
* We are iterating through the three sides of the scope at the same time so that index might apply
* pre-matching strategies elements if they wish.
*/
while (leftEObjects.hasNext() || rightEObjects.hasNext() || leftEObjects.hasNext()) {
+
if (leftEObjects.hasNext()) {
- index.index(leftEObjects.next(), Side.LEFT);
+ EObject next = leftEObjects.next();
+ nbElements++;
+ index.index(next, Side.LEFT);
+ eObjectsToSide.put(next, Side.LEFT);
}
+
if (rightEObjects.hasNext()) {
- index.index(rightEObjects.next(), Side.RIGHT);
+ EObject next = rightEObjects.next();
+ nbElements++;
+ index.index(next, Side.RIGHT);
+ eObjectsToSide.put(next, Side.RIGHT);
}
+
if (originEObjects.hasNext()) {
- index.index(originEObjects.next(), Side.ORIGIN);
+ EObject next = originEObjects.next();
+ nbElements++;
+ index.index(next, Side.ORIGIN);
+ eObjectsToSide.put(next, Side.ORIGIN);
}
}
+ monitor.done();
+ monitor.beginTask("matching objects", nbElements);
- for (EObject left : index.getValuesStillThere(Side.LEFT)) {
- Map<Side, EObject> closests = index.findClosests(left, Side.LEFT);
- EObject right = closests.get(Side.RIGHT);
- EObject ancestor = closests.get(Side.ORIGIN);
- areMatching(left, right, ancestor);
- if (right != null) {
- index.remove(right, Side.RIGHT);
- }
- index.remove(left, Side.LEFT);
- if (ancestor != null) {
- index.remove(ancestor, Side.ORIGIN);
- }
+ Iterator<EObject> todo = index.getValuesStillThere(Side.LEFT).iterator();
+ while (todo.hasNext()) {
+ Iterator<EObject> remainingResult = matchList(comparison, todo, monitor).iterator();
+ todo = remainingResult;
}
-
- /*
- * now we have to process the remaining objects starting from the right index and trying to match an l
- * object.
- */
- for (EObject rObj : index.getValuesStillThere(Side.RIGHT)) {
- Map<Side, EObject> closests = index.findClosests(rObj, Side.RIGHT);
- EObject lObj = closests.get(Side.LEFT);
- EObject aObj = closests.get(Side.ORIGIN);
- areMatching(lObj, rObj, aObj);
- index.remove(rObj, Side.RIGHT);
- if (lObj != null) {
- index.remove(lObj, Side.LEFT);
- }
- if (aObj != null) {
- index.remove(aObj, Side.ORIGIN);
- }
+ todo = index.getValuesStillThere(Side.RIGHT).iterator();
+ while (todo.hasNext()) {
+ Iterator<EObject> remainingResult = matchList(comparison, todo, monitor).iterator();
+ todo = remainingResult;
}
for (EObject notFound : index.getValuesStillThere(Side.RIGHT)) {
- areMatching(null, notFound, null);
- index.remove(notFound, Side.RIGHT);
+ areMatching(comparison, null, notFound, null);
}
for (EObject notFound : index.getValuesStillThere(Side.LEFT)) {
- areMatching(notFound, null, null);
- index.remove(notFound, Side.LEFT);
+ areMatching(comparison, notFound, null, null);
}
for (EObject notFound : index.getValuesStillThere(Side.ORIGIN)) {
- areMatching(null, null, notFound);
- index.remove(notFound, Side.ORIGIN);
+ areMatching(comparison, null, null, notFound);
}
- restructureMatchModel();
+ monitor.done();
+ restructureMatchModel(comparison);
+
+ }
+
+ /**
+ * Process the list of objects matching them. This method might not be able to process all the EObjects if
+ * - for instance, their container has not been matched already. Every object which could not be matched
+ * is returned in the list.
+ *
+ * @param comparison
+ * the comparison being built.
+ * @param todo
+ * the list of objects to process.
+ * @param monitor
+ * a monitor to track progress.
+ * @return the list of
+ */
+ private Iterable<EObject> matchList(Comparison comparison, Iterator<EObject> todo, Monitor monitor) {
+ List<EObject> remainingResult = Lists.newArrayList();
+ while (todo.hasNext()) {
+ EObject next = todo.next();
+ if (next.eContainer() == null || comparison.getMatch(next.eContainer()) != null
+ || !isInScope(next.eContainer())) {
+ if (!tryToMatch(comparison, next)) {
+ remainingResult.add(next);
+ }
+ monitor.worked(1);
+ } else {
+ remainingResult.add(next);
+ }
+ }
+ return remainingResult;
+ }
- return matches;
+ /**
+ * Try to create a Match. If the match got created, register it (having actual left/right/origin matches
+ * or not), if not, then return false. Cases where it might not create the match : if some required data
+ * has not been computed yet (for instance if the container of an object has not been matched and if the
+ * distance need to know if it's match to find the children matches).
+ *
+ * @param comparison
+ * the comparison under construction, it will be updated with the new match.
+ * @param a
+ * object to match.
+ * @return false if the conditions are not fulfilled to create the match, true otherwhise.
+ */
+ private boolean tryToMatch(Comparison comparison, EObject a) {
+ Side aSide = eObjectsToSide.get(a);
+ assert aSide != null;
+ Side bSide = Side.LEFT;
+ Side cSide = Side.RIGHT;
+ if (aSide == Side.RIGHT) {
+ bSide = Side.LEFT;
+ cSide = Side.ORIGIN;
+ } else if (aSide == Side.LEFT) {
+ bSide = Side.RIGHT;
+ cSide = Side.ORIGIN;
+ } else if (aSide == Side.ORIGIN) {
+ bSide = Side.LEFT;
+ cSide = Side.RIGHT;
+ }
+ assert aSide != bSide;
+ assert bSide != cSide;
+ assert cSide != aSide;
+ Map<Side, EObject> closests = index.findClosests(comparison, a, aSide);
+ if (closests != null) {
+ EObject lObj = closests.get(bSide);
+ EObject aObj = closests.get(cSide);
+ areMatching(comparison, closests.get(Side.LEFT), closests.get(Side.RIGHT), closests
+ .get(Side.ORIGIN));
+ if (lObj != null) {
+ index.remove(lObj, Side.LEFT);
+ }
+ if (aObj != null) {
+ index.remove(aObj, Side.ORIGIN);
+ }
+ if (a != null) {
+ index.remove(a, Side.RIGHT);
+ }
+ return true;
+ }
+ return false;
}
/**
- * Process all the matches and re-attach them to their parent if one is found.
+ * Process all the matches of the given comparison and re-attach them to their parent if one is found.
+ *
+ * @param comparison
+ * the comparison to restructure.
*/
- private void restructureMatchModel() {
- Iterator<Match> it = matches.iterator();
+ private void restructureMatchModel(Comparison comparison) {
+ Iterator<Match> it = ImmutableList.copyOf(Iterators.filter(comparison.eAllContents(), Match.class))
+ .iterator();
while (it.hasNext()) {
Match cur = it.next();
@@ -158,17 +236,18 @@ public class ProximityEObjectMatcher implements IEObjectMatcher {
if (possibleContainer == null && cur.getOrigin() != null) {
possibleContainer = cur.getOrigin().eContainer();
}
- Match possibleContainerMatch = eObjectsToMatch.get(possibleContainer);
+ Match possibleContainerMatch = comparison.getMatch(possibleContainer);
if (possibleContainerMatch != null) {
((BasicEList<Match>)possibleContainerMatch.getSubmatches()).addUnique(cur);
- it.remove();
}
}
}
/**
- * Register the given object as a match.
+ * Register the given object as a match and add it in the comparison.
*
+ * @param comparison
+ * container for the Match.
* @param left
* left element.
* @param right
@@ -177,22 +256,19 @@ public class ProximityEObjectMatcher implements IEObjectMatcher {
* origin element.
* @return the created match.
*/
- private Match areMatching(EObject left, EObject right, EObject origin) {
+ private Match areMatching(Comparison comparison, EObject left, EObject right, EObject origin) {
Match result = CompareFactory.eINSTANCE.createMatch();
result.setLeft(left);
result.setRight(right);
result.setOrigin(origin);
- matches.add(result);
+ ((BasicEList<Match>)comparison.getMatches()).addUnique(result);
if (left != null) {
- eObjectsToMatch.put(left, result);
index.remove(left, Side.LEFT);
}
if (right != null) {
- eObjectsToMatch.put(right, result);
index.remove(right, Side.RIGHT);
}
if (origin != null) {
- eObjectsToMatch.put(origin, result);
index.remove(origin, Side.ORIGIN);
}
return result;
@@ -218,6 +294,9 @@ public class ProximityEObjectMatcher implements IEObjectMatcher {
* Return the distance between two EObjects. When the two objects should considered as completely
* different the implementation is expected to return Integer.MAX_VALUE.
*
+ * @param inProgress
+ * the comparison being processed right now. This might be used for the distance to
+ * retrieve other matches for instance.
* @param a
* first object.
* @param b
@@ -225,19 +304,30 @@ public class ProximityEObjectMatcher implements IEObjectMatcher {
* @return the distance between the two EObjects or Integer.MAX_VALUE when the objects are considered
* too different to be the same.
*/
- int distance(EObject a, EObject b);
+ double distance(Comparison inProgress, EObject a, EObject b);
/**
* Check that two objects are equals from the distance function point of view (distance should be 0)
* You should prefer this method when you just want to check objects are not equals enabling the
* distance to stop sooner.
*
+ * @param inProgress
+ * the comparison being processed right now. This might be used for the distance to
+ * retrieve other matches for instance.
* @param a
* first object.
* @param b
* second object.
* @return true of the two objects are equals, false otherwise.
*/
- boolean areIdentic(EObject a, EObject b);
+ boolean areIdentic(Comparison inProgress, EObject a, EObject b);
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isInScope(EObject eContainer) {
+ return eObjectsToSide.get(eContainer) != null;
}
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityIndex.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityIndex.java
index 4fe9c1c43..c9f014d64 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityIndex.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityIndex.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.compare.match.eobject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import java.util.Collection;
import java.util.Collections;
@@ -19,8 +20,12 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EcoreFactory;
/**
* This class is responsible for holding several version of EObjects from sides left, right or origins and
@@ -37,6 +42,12 @@ import org.eclipse.emf.ecore.EObject;
*/
public class ProximityIndex implements EObjectIndex {
/**
+ * Null object pattern, this object is returned when the index had to backtrack and as such could not even
+ * try to find the match.
+ */
+ private static final EObject BACKTRACK = EcoreFactory.eINSTANCE.createEClass();
+
+ /**
* The distance function used to compare the Objects.
*/
private ProximityEObjectMatcher.DistanceFunction meter;
@@ -57,16 +68,29 @@ public class ProximityIndex implements EObjectIndex {
private List<EObject> origins;
/**
+ * An object able to tell us whether an object is in the scope or not.
+ */
+ private ScopeQuery scope;
+
+ /**
+ * An object to gather statistics while matching.
+ */
+ private ProximityMatchStats stats = new ProximityMatchStats();
+
+ /**
* Create a new {@link ProximityIndex} using the given distance function.
*
* @param meter
* the distance function to use to compare the EObjects.
+ * @param matcher
+ * the object used to know if an instance is in the scope or not.
*/
- public ProximityIndex(ProximityEObjectMatcher.DistanceFunction meter) {
+ public ProximityIndex(ProximityEObjectMatcher.DistanceFunction meter, ScopeQuery matcher) {
this.meter = meter;
this.lefts = Lists.newArrayList();
this.rights = Lists.newArrayList();
this.origins = Lists.newArrayList();
+ this.scope = matcher;
}
@@ -74,25 +98,26 @@ public class ProximityIndex implements EObjectIndex {
* {@inheritDoc}
*/
- public Map<Side, EObject> findClosests(EObject eObj, Side passedObjectSide) {
-
+ public Map<Side, EObject> findClosests(Comparison inProgress, EObject eObj, Side passedObjectSide) {
+ if (!readyForThisTest(inProgress, eObj)) {
+ return null;
+ }
Map<Side, EObject> result = new HashMap<EObjectIndex.Side, EObject>(3);
-
result.put(passedObjectSide, eObj);
if (passedObjectSide == Side.LEFT) {
- EObject closestRight = findTheClosest(eObj, Side.LEFT, Side.RIGHT, true);
- EObject closestOrigin = findTheClosest(eObj, Side.LEFT, Side.ORIGIN, true);
+ EObject closestRight = findTheClosest(inProgress, eObj, Side.LEFT, Side.RIGHT, true);
+ EObject closestOrigin = findTheClosest(inProgress, eObj, Side.LEFT, Side.ORIGIN, true);
result.put(Side.RIGHT, closestRight);
result.put(Side.ORIGIN, closestOrigin);
} else if (passedObjectSide == Side.RIGHT) {
- EObject closestLeft = findTheClosest(eObj, Side.RIGHT, Side.LEFT, true);
- EObject closestOrigin = findTheClosest(eObj, Side.RIGHT, Side.ORIGIN, true);
+ EObject closestLeft = findTheClosest(inProgress, eObj, Side.RIGHT, Side.LEFT, true);
+ EObject closestOrigin = findTheClosest(inProgress, eObj, Side.RIGHT, Side.ORIGIN, true);
result.put(Side.LEFT, closestLeft);
result.put(Side.ORIGIN, closestOrigin);
} else if (passedObjectSide == Side.ORIGIN) {
- EObject closestLeft = findTheClosest(eObj, Side.ORIGIN, Side.LEFT, true);
- EObject closestRight = findTheClosest(eObj, Side.ORIGIN, Side.RIGHT, true);
+ EObject closestLeft = findTheClosest(inProgress, eObj, Side.ORIGIN, Side.LEFT, true);
+ EObject closestRight = findTheClosest(inProgress, eObj, Side.ORIGIN, Side.RIGHT, true);
result.put(Side.LEFT, closestLeft);
result.put(Side.RIGHT, closestRight);
}
@@ -104,6 +129,8 @@ public class ProximityIndex implements EObjectIndex {
/**
* return the closest EObject of the passed one found in the sideToFind storage.
*
+ * @param inProgress
+ * the comparison under match.
* @param eObj
* the base EObject.
* @param originalSide
@@ -115,8 +142,8 @@ public class ProximityIndex implements EObjectIndex {
* base one.
* @return the closest EObject of the passed one found in the sideToFind storage.
*/
- private EObject findTheClosest(final EObject eObj, final Side originalSide, final Side sideToFind,
- boolean shouldDoubleCheck) {
+ private EObject findTheClosest(Comparison inProgress, final EObject eObj, final Side originalSide,
+ final Side sideToFind, boolean shouldDoubleCheck) {
List<EObject> storageToSearchFor = lefts;
switch (sideToFind) {
case RIGHT:
@@ -138,48 +165,102 @@ public class ProximityIndex implements EObjectIndex {
* is also based on the assumption that calling distance() with a 0 max distance triggers shortcuts
* and is faster than calling the same distance() method with a max_distance > 0.
*/
- EObject best = null;
- int bestDist = Integer.MAX_VALUE;
- Iterator<EObject> it = storageToSearchFor.iterator();
- while (it.hasNext() && best == null) {
- EObject fastCheck = it.next();
- if (meter.areIdentic(eObj, fastCheck)) {
- best = fastCheck;
- bestDist = 0;
- }
- }
-
- if (best != null) {
- return best;
+ Candidate best = findIdenticMatch(inProgress, eObj, storageToSearchFor);
+ if (best.some()) {
+ return best.eObject;
}
+ SortedMap<Double, EObject> candidates = Maps.newTreeMap();
/*
* We could not find an EObject which is identical, let's search again and find the closest EObject.
*/
- it = storageToSearchFor.iterator();
- while (bestDist != 0 && it.hasNext()) {
+ Iterator<EObject> it = storageToSearchFor.iterator();
+ while (best.distance != 0 && it.hasNext()) {
EObject potentialClosest = it.next();
- int dist = meter.distance(eObj, potentialClosest);
- if (dist < bestDist) {
+ double dist = meter.distance(inProgress, eObj, potentialClosest);
+ stats.similarityCompare();
+ if (dist < best.distance) {
if (shouldDoubleCheck) {
// We need to double check the currentlyDigging has the same object as the closest !
-
- EObject doubleCheck = findTheClosest(potentialClosest, sideToFind, originalSide, false);
- if (doubleCheck == eObj) {
- bestDist = dist;
- best = potentialClosest;
- }
+ candidates.put(Double.valueOf(dist), potentialClosest);
} else {
- bestDist = dist;
- best = potentialClosest;
+ best.distance = dist;
+ best.eObject = potentialClosest;
}
}
}
+ if (shouldDoubleCheck) {
+ for (Entry<Double, EObject> entry : candidates.entrySet()) {
+ EObject doubleCheck = findTheClosest(inProgress, entry.getValue(), sideToFind, originalSide,
+ false);
+ stats.doubleCheck();
+ if (doubleCheck == eObj) {
+ stats.similaritySuccess();
+ best.eObject = entry.getValue();
+ best.distance = Double.valueOf(entry.getKey());
+ break;
+ } else {
+ stats.failedDoubleCheck();
+ }
+ }
+ }
+
+ if (!best.some()) {
+ stats.noMatch();
+ }
+ return best.eObject;
+ }
+ /**
+ * Look for a perfect match (identic content) in the given list of candidates.
+ *
+ * @param inProgress
+ * the comparison being matched.
+ * @param eObj
+ * the object
+ * @param candidates
+ * the list of possible matches.
+ * @return a candidate instance wrapping the found match Object (if found)
+ */
+ private Candidate findIdenticMatch(Comparison inProgress, final EObject eObj, List<EObject> candidates) {
+ Iterator<EObject> it = candidates.iterator();
+ Candidate best = new Candidate();
+
+ while (it.hasNext() && !best.some()) {
+ EObject fastCheck = it.next();
+ if (!readyForThisTest(inProgress, fastCheck)) {
+ stats.backtrack();
+ best.eObject = BACKTRACK;
+ } else {
+ stats.identicCompare();
+ if (meter.areIdentic(inProgress, eObj, fastCheck)) {
+ stats.identicSuccess();
+ best.eObject = fastCheck;
+ best.distance = 0;
+ }
+ }
+ }
return best;
}
/**
+ * Check whether we have all the required information to search for this object matches.
+ *
+ * @param inProgress
+ * the Comparison which is being matched.
+ * @param fastCheck
+ * the Object we are trying to match.
+ * @return true if we have all the required information, false otherwise.
+ */
+ private boolean readyForThisTest(Comparison inProgress, EObject fastCheck) {
+ if (fastCheck.eContainer() != null) {
+ return inProgress.getMatch(fastCheck.eContainer()) != null
+ || scope.isInScope(fastCheck.eContainer());
+ }
+ return true;
+ }
+
+ /**
* {@inheritDoc}
*/
public void remove(EObject obj, Side side) {
@@ -242,4 +323,30 @@ public class ProximityIndex implements EObjectIndex {
}
+ /**
+ * A Wrapper class to keep an {@link EObject} aside with a distance.
+ *
+ * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
+ */
+ class Candidate {
+ /**
+ * an EObject.
+ */
+ EObject eObject;
+
+ /**
+ * A distance.
+ */
+ double distance = Double.MAX_VALUE;
+
+ /**
+ * return true of the candidate has an {@link EObject}.
+ *
+ * @return true of the candidate has an {@link EObject}.
+ */
+ public boolean some() {
+ return eObject != null;
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityMatchStats.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityMatchStats.java
new file mode 100644
index 000000000..b00514572
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ProximityMatchStats.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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;
+
+/**
+ * A class responsible for tracking statistics about a given comparison process.
+ *
+ * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
+ */
+public class ProximityMatchStats {
+ /**
+ * number of comparison dones looking for identic objects.
+ */
+ private int nbIndenticComparison;
+
+ /**
+ * number of comparison dones looking for similar objects.
+ */
+ private int nbMaxDistComparison;
+
+ /**
+ * number of match not found.
+ */
+ private int nbNoMatch;
+
+ /**
+ * number of match found using the identic comparison.
+ */
+ private int nbSuccessIdenticComparison;
+
+ /**
+ * number of match found using the similarity comparison.
+ */
+ private int nbSuccessMaxComparison;
+
+ /**
+ * number of backtracks we had to do.
+ */
+ private int nbBacktrack;
+
+ /**
+ * number of double check done.
+ */
+ private int nbDoubleCheck;
+
+ /**
+ * number of double check which failed.
+ */
+ private int nbFailedDoubleCheck;
+
+ /**
+ * A backtrack has been done.
+ */
+ public void backtrack() {
+ nbBacktrack++;
+ }
+
+ /**
+ * We successfully matched two objects while trying to find identic objects.
+ */
+ public void identicSuccess() {
+ nbSuccessIdenticComparison++;
+ }
+
+ /**
+ * We compared two objects looking for identic objects.
+ */
+ public void identicCompare() {
+ nbIndenticComparison++;
+ }
+
+ /**
+ * We compared two objects by their similarity.
+ */
+ public void similarityCompare() {
+ nbMaxDistComparison++;
+ }
+
+ /**
+ * Double checked a candidate pair of match.
+ */
+ public void doubleCheck() {
+ nbDoubleCheck++;
+
+ }
+
+ /**
+ * We achieved a match using similarity.
+ */
+ public void similaritySuccess() {
+ nbSuccessMaxComparison++;
+
+ }
+
+ /**
+ * A double check has failed.
+ */
+ public void failedDoubleCheck() {
+ nbFailedDoubleCheck++;
+ }
+
+ /**
+ * We found no match for an Object.
+ */
+ public void noMatch() {
+ nbNoMatch++;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "ProximityMatchStats [nbIndenticComparison=" + nbIndenticComparison + ", nbMaxDistComparison="
+ + nbMaxDistComparison + ", nbnoMatch=" + nbNoMatch + ", nbSuccessIdenticComparison="
+ + nbSuccessIdenticComparison + ", nbSuccessMaxComparison=" + nbSuccessMaxComparison
+ + ", nbBacktrack=" + nbBacktrack + ", nbDoubleCheck=" + nbDoubleCheck
+ + ", nbFailedDoubleCheck=" + nbFailedDoubleCheck + "]";
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ReflectiveWeightProvider.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ReflectiveWeightProvider.java
index 175946797..9a0118866 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ReflectiveWeightProvider.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ReflectiveWeightProvider.java
@@ -16,8 +16,13 @@ import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Set;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl;
/**
* Default implementation which is parameterized to set weights based on features, to ignore features and
@@ -38,6 +43,16 @@ public class ReflectiveWeightProvider implements WeightProvider {
private Set<EStructuralFeature> toBeIgnored;
/**
+ * Weight coefficient of a change on a reference.
+ */
+ private int referenceChangeCoef = 2;
+
+ /**
+ * Weight coefficient of a change on an attribute.
+ */
+ private int attributeChangeCoef = 5;
+
+ /**
* Create the weight provider.
*/
public ReflectiveWeightProvider() {
@@ -56,18 +71,25 @@ public class ReflectiveWeightProvider implements WeightProvider {
Integer found = weights.get(feature);
if (found == null) {
+ found = Integer.valueOf(1);
/*
* 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())) { //$NON-NLS-1$
+ if ("name".equals(feature.getName()) || "id".equals(feature.getName())) { //$NON-NLS-1$
found = Integer.valueOf(4);
- } else {
- found = Integer.valueOf(1);
}
+ if (feature instanceof EReference && ((EReference)feature).isContainment()) {
+ found = Integer.valueOf(2);
+ }
+ }
+ if (feature instanceof EReference) {
+ found = referenceChangeCoef * found.intValue();
+ } else {
+ found = attributeChangeCoef * found.intValue();
}
- return found.intValue();
+ return found;
}
/**
@@ -85,4 +107,44 @@ public class ReflectiveWeightProvider implements WeightProvider {
}
return irrelevantFeature;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ // CHECKSTYLE:OFF
+ public int getParentWeight(EObject a) {
+ /*
+ * these should belong to an Ecore specific class
+ */
+ if (a instanceof EStructuralFeature) {
+ return 34;
+ } else if (a instanceof EAnnotation) {
+ return 34;
+ } else if (a instanceof EOperation) {
+ return 20;
+ } else if (a instanceof EParameter) {
+ return 30;
+ } else if (a instanceof EStringToStringMapEntryImpl) {
+ return 30;
+ }
+ return 1;
+ }
+
+ // CHECKSTYLE:ON
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getContainingFeatureWeight(EObject a) {
+ /*
+ * these should belong to an ECore specific class
+ */
+ // CHECKSTYLE:OFF
+ if (a instanceof EStructuralFeature || a instanceof EAnnotation || a instanceof EOperation) {
+ return 20;
+ }
+ // CHECKSTYLE:ON
+ return 1;
+ }
+
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ScopeQuery.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ScopeQuery.java
new file mode 100644
index 000000000..34bdd5150
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/ScopeQuery.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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 org.eclipse.emf.ecore.EObject;
+
+/**
+ * A class implementing this contract should have the ability to query the scope and tell, from a given
+ * EObject, if it is in the scope or not. Implementation should not trigger any kind of proxy resolution.
+ *
+ * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
+ */
+public interface ScopeQuery {
+ /**
+ * Check whether the object is in the scope or not.
+ *
+ * @param any
+ * any EObject.
+ * @return true if the Object is in scope. False otherwise.
+ */
+ boolean isInScope(EObject any);
+}
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 4a91bf2a4..d5c4c0ef4 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
@@ -11,6 +11,7 @@
package org.eclipse.emf.compare.match.eobject;
import com.google.common.base.Function;
+import com.google.common.base.Optional;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@@ -20,9 +21,9 @@ import com.google.common.collect.Lists;
import java.util.Iterator;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Match;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.InternalEObject;
/**
* This class is able to measure similarity between "URI like" strings, basically strings separated by "/".
@@ -42,10 +43,35 @@ public class URIDistance implements Function<EObject, Iterable<String>> {
private Cache<EObject, Iterable<String>> locationCache;
/**
+ * A computing cache for the uri fragments.
+ */
+ private Cache<EObject, String> fragmentsCache;
+
+ /**
+ * An optional comparison to retrieve matches already computed. This will impact the way the uri is
+ * computed by making sure two matching objects will have the same URI.
+ */
+ private Optional<Comparison> underMatch = Optional.absent();
+
+ /**
* Create a new {@link URIDistance}.
*/
public URIDistance() {
locationCache = CacheBuilder.newBuilder().maximumSize(10000).build(CacheLoader.from(this));
+ fragmentsCache = CacheBuilder.newBuilder().maximumSize(10000).build(
+ CacheLoader.from(new EUriFragmentFunction()));
+ // CHECKSTYLE:ON
+ }
+
+ /**
+ * Set an optional comparison used to retrieve matches already computed. This will impact the way the uri
+ * is computed by making sure two matching objects will have the same URI.
+ *
+ * @param comparison
+ * the comparison to use to retrieve the matches.
+ */
+ public void setComparison(Comparison comparison) {
+ this.underMatch = Optional.fromNullable(comparison);
}
/**
@@ -113,14 +139,20 @@ public class URIDistance implements Function<EObject, Iterable<String>> {
* @see com.google.common.base.Function#apply(java.lang.Object)
*/
public Iterable<String> apply(EObject input) {
- EObject cur = input;
String result = ""; //$NON-NLS-1$
EObject container = input.eContainer();
if (container != null) {
- EStructuralFeature feat = cur.eContainingFeature();
- if (input instanceof InternalEObject) {
- String frag = ((InternalEObject)container).eURIFragmentSegment(feat, cur);
- result = frag;
+ if (underMatch.isPresent()) {
+ /*
+ * If we have a match for the container, we want to make sure the fragment is going to be the
+ * same.
+ */
+ Match m = underMatch.get().getMatch(container);
+ if (m == null) {
+ result = retrieveFragment(input);
+ }
+ } else {
+ result = retrieveFragment(input);
}
} else {
result = "0"; //$NON-NLS-1$
@@ -134,6 +166,17 @@ public class URIDistance implements Function<EObject, Iterable<String>> {
}
/**
+ * the containing fragment for a given {@link EObject}.
+ *
+ * @param input
+ * an EObject.
+ * @return a String representation of its containing fragment.
+ */
+ public String retrieveFragment(EObject input) {
+ return fragmentsCache.getUnchecked(input);
+ }
+
+ /**
* return the maximum value we can get for this distance.
*
* @return the maximum value we can get for this distance.
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/WeightProvider.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/WeightProvider.java
index 7c280afea..279bf0a7b 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/WeightProvider.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/match/eobject/WeightProvider.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.emf.compare.match.eobject;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
/**
@@ -28,4 +29,22 @@ public interface WeightProvider {
*/
int getWeight(EStructuralFeature attribute);
+ /**
+ * Return the weight associated with the fact some Object has changed it's container.
+ *
+ * @param a
+ * any instance.
+ * @return a weight representing the importance of the change of container to compute matches.
+ */
+ int getParentWeight(EObject a);
+
+ /**
+ * Return the weight associated with the fact some Object has changed it's containing reference.
+ *
+ * @param a
+ * any instance.
+ * @return a weight representing the importance of the change of containing reference to compute matches.
+ */
+ int getContainingFeatureWeight(EObject a);
+
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/EqualityHelper.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/EqualityHelper.java
index e5d0f787b..fa3b67675 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/EqualityHelper.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/EqualityHelper.java
@@ -109,13 +109,13 @@ public class EqualityHelper extends AdapterImpl implements IEqualityHelper {
} else if (converted1 instanceof EObject && converted2 instanceof EObject) {
// [248442] This will handle FeatureMapEntries detection
equal = matchingEObjects((EObject)converted1, (EObject)converted2);
+ } else if (isNullOrEmptyString(converted1) && isNullOrEmptyString(converted2)) {
+ // Special case, consider that the empty String is equal to null (unset attributes)
+ equal = true;
} else if (converted1 != null && converted1.getClass().isArray() && converted2 != null
&& converted2.getClass().isArray()) {
// [299641] compare arrays by their content instead of instance equality
equal = matchingArrays(converted1, converted2);
- } else if (isNullOrEmptyString(converted1) && isNullOrEmptyString(converted2)) {
- // Special case, consider that the empty String is equal to null (unset attributes)
- equal = true;
} else {
equal = converted1 != null && converted1.equals(converted2);
}

Back to the top