From fcf2ff0e2d9f8b8e3f28d7ea64f19a114e026000 Mon Sep 17 00:00:00 2001 From: Sebastian Krings <sebastian@krin.gs> Date: Tue, 27 Jan 2015 10:47:46 +0100 Subject: [PATCH] try to integrate a custom match engine for eventb --- .../eventb/texttools/PersistenceHelper.java | 19 ++- .../texttools/merge/EventBMatchEngine.java | 20 ++++ .../merge/EventBResourceMatcher.java | 109 ++++++++++++++++++ 3 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 org.eventb.texttools/src/org/eventb/texttools/merge/EventBMatchEngine.java create mode 100644 org.eventb.texttools/src/org/eventb/texttools/merge/EventBResourceMatcher.java diff --git a/org.eventb.texttools/src/org/eventb/texttools/PersistenceHelper.java b/org.eventb.texttools/src/org/eventb/texttools/PersistenceHelper.java index 41dc656..2b8cf28 100644 --- a/org.eventb.texttools/src/org/eventb/texttools/PersistenceHelper.java +++ b/org.eventb.texttools/src/org/eventb/texttools/PersistenceHelper.java @@ -44,7 +44,7 @@ import org.eventb.emf.core.AttributeType; import org.eventb.emf.core.CoreFactory; import org.eventb.emf.core.EventBElement; import org.eventb.emf.core.EventBNamedCommentedComponentElement; -//import org.eventb.texttools.merge.ModelMerge; +import org.eventb.texttools.merge.EventBMatchEngine; import org.eventb.texttools.prettyprint.PrettyPrinter; import de.be4.eventb.core.parser.BException; @@ -54,6 +54,8 @@ import de.be4.eventb.core.parser.node.AMachineParseUnit; import de.be4.eventb.core.parser.node.PParseUnit; import de.be4.eventb.core.parser.node.Start; +//import org.eventb.texttools.merge.ModelMerge; + public class PersistenceHelper { public static final Boolean DEBUG = false; @@ -160,12 +162,21 @@ public class PersistenceHelper { try { long time0 = System.currentTimeMillis(); - IEObjectMatcher matcher = DefaultMatchEngine - .createDefaultEObjectMatcher(UseIdentifiers.NEVER); IComparisonFactory comparisonFactory = new DefaultComparisonFactory( new DefaultEqualityHelperFactory()); - IMatchEngine.Factory matchEngineFactory = new MatchEngineFactoryImpl( + + IEObjectMatcher matcher = DefaultMatchEngine + .createDefaultEObjectMatcher(UseIdentifiers.NEVER); + + final IMatchEngine eventBMatchEngine = new EventBMatchEngine( matcher, comparisonFactory); + + IMatchEngine.Factory matchEngineFactory = new MatchEngineFactoryImpl() { + @Override + public IMatchEngine getMatchEngine() { + return eventBMatchEngine; + } + }; matchEngineFactory.setRanking(20); IMatchEngine.Factory.Registry matchEngineRegistry = new MatchEngineFactoryRegistryImpl(); matchEngineRegistry.add(matchEngineFactory); diff --git a/org.eventb.texttools/src/org/eventb/texttools/merge/EventBMatchEngine.java b/org.eventb.texttools/src/org/eventb/texttools/merge/EventBMatchEngine.java new file mode 100644 index 0000000..e34ef81 --- /dev/null +++ b/org.eventb.texttools/src/org/eventb/texttools/merge/EventBMatchEngine.java @@ -0,0 +1,20 @@ +package org.eventb.texttools.merge; + +import org.eclipse.emf.compare.match.DefaultMatchEngine; +import org.eclipse.emf.compare.match.IComparisonFactory; +import org.eclipse.emf.compare.match.eobject.IEObjectMatcher; +import org.eclipse.emf.compare.match.resource.IResourceMatcher; + +public class EventBMatchEngine extends DefaultMatchEngine { + + public EventBMatchEngine(IEObjectMatcher matcher, + IComparisonFactory comparisonFactory) { + super(matcher, comparisonFactory); + } + + @Override + protected IResourceMatcher createResourceMatcher() { + return new EventBResourceMatcher(); + } + +} diff --git a/org.eventb.texttools/src/org/eventb/texttools/merge/EventBResourceMatcher.java b/org.eventb.texttools/src/org/eventb/texttools/merge/EventBResourceMatcher.java new file mode 100644 index 0000000..d7467ee --- /dev/null +++ b/org.eventb.texttools/src/org/eventb/texttools/merge/EventBResourceMatcher.java @@ -0,0 +1,109 @@ +package org.eventb.texttools.merge; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.match.resource.StrategyResourceMatcher; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eventb.emf.core.EventBNamed; +import org.eventb.emf.core.machine.Event; +import org.eventb.emf.core.machine.Variant; + +import com.google.common.collect.Lists; + +public class EventBResourceMatcher extends StrategyResourceMatcher { + @Override + public Iterable<MatchResource> createMappings( + Iterator<? extends Resource> leftResources, + Iterator<? extends Resource> rightResources, + Iterator<? extends Resource> originResources) { + final List<MatchResource> mappings = Lists.newArrayList(); + + final List<? extends Resource> leftCopy = Lists + .newArrayList(leftResources); + final List<? extends Resource> rightCopy = Lists + .newArrayList(rightResources); + final List<? extends Resource> originCopy = Lists + .newArrayList(originResources); + + // only two way merge in camille?! + assert (originCopy.isEmpty()); + + for (Resource left : leftCopy) { + Resource right = findMatch(left, rightCopy); + leftCopy.remove(left); + rightCopy.remove(right); + mappings.add(createMatchResource(left, right, null)); + } + + // further matches (including the left-only / right-only ones are found + // by the default strategies + Iterable<MatchResource> superMappings = super.createMappings( + leftCopy.iterator(), rightCopy.iterator(), + originCopy.iterator()); + + for (MatchResource matchResource : superMappings) { + mappings.add(matchResource); + } + + return mappings; + } + + protected Resource findMatch(Resource reference, + List<? extends Resource> rightCopy) { + for (Resource candidate : rightCopy) { + if (matching(reference, candidate)) { + rightCopy.remove(candidate); + return candidate; + } + } + return null; + } + + // this logic was previously found in isSimiliar of EventBMatchEngine + private boolean matching(Resource reference, Resource candidate) { + /* + * Only one variant may exist in a model, so two variants are a match + */ + // FIXME: type of reference / resource + // if (areVariants(reference, candidate)) { + // return true; + // } + + /* + * Improve matching for event b named objects with same name + */ + if (reference instanceof EventBNamed + && candidate instanceof EventBNamed) { + Event r = (Event) reference; + Event c = (Event) reference; + + if (r.getName().equals(c.getName())) { + return true; + } + } + + // false => the default behaviour of StrategyResourceMatcher will be + // tried afterwards + return false; + } + + private boolean areSameType(final EObject obj1, final EObject obj2) { + return obj1 != null && obj2 != null + && obj1.eClass().equals(obj2.eClass()); + } + + /** + * Test if both given {@link EObject}s are of type {@link Variant}, includes + * <code>null</code> check. + * + * @param obj1 + * @param obj2 + * @return + */ + private boolean areVariants(final EObject obj1, final EObject obj2) { + return areSameType(obj1, obj2) && obj2 instanceof Variant; + } +} -- GitLab