Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java')
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java166
1 files changed, 166 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java
new file mode 100644
index 000000000..022f3d7b3
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/merge/MergeDependenciesUtil.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.internal.merge;
+
+import com.google.common.collect.Sets;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.merge.IMerger2;
+
+/**
+ * Factorizes utilities used throughout EMF Compare to explore merge dependencies.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+public final class MergeDependenciesUtil {
+ /** Hides default constructor. */
+ private MergeDependenciesUtil() {
+ // Hides default constructor
+ }
+
+ /**
+ * Retrieves the set of all diffs related to the given <code>diff</code> when merging in the given
+ * direction.
+ * <p>
+ * This is expected to return the set of all differences that will be need to merged along when a user
+ * wishes to merge <code>diff</code>, either because they are required by it or because they are implied
+ * by it one way or another.
+ * </p>
+ * <p>
+ * Note that <code>diff</code> will be included in the returned set.
+ * </p>
+ *
+ * @param diff
+ * The difference for which we seek all related ones.
+ * @param mergerRegistry
+ * The {@link IMerger.Registry merger registry} currently in use.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return The set of all diffs related to the given <code>diff</code> when merging in the given
+ * direction.
+ */
+ public static Set<Diff> getAllResultingMerges(Diff diff, IMerger.Registry mergerRegistry,
+ boolean mergeRightToLeft) {
+ final Set<Diff> resultingMerges = new LinkedHashSet<Diff>();
+ resultingMerges.add(diff);
+
+ Set<Diff> relations = internalGetResultingMerges(diff, mergerRegistry, mergeRightToLeft);
+ Set<Diff> difference = Sets.difference(relations, resultingMerges);
+ while (!difference.isEmpty()) {
+ final Set<Diff> newRelations = new LinkedHashSet<Diff>(difference);
+ resultingMerges.addAll(newRelations);
+ relations = new LinkedHashSet<Diff>();
+ for (Diff newRelation : newRelations) {
+ relations.addAll(internalGetResultingMerges(newRelation, mergerRegistry, mergeRightToLeft));
+ }
+ difference = Sets.difference(relations, resultingMerges);
+ }
+
+ return resultingMerges;
+ }
+
+ /**
+ * Returns the set of all differences <b>directly</b> related to the given one, either as dependencies or
+ * as implications.
+ *
+ * @param diff
+ * The difference for which we seek all directly related others.
+ * @param mergerRegistry
+ * The {@link IMerger.Registry merger registry} currently in use.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return The set of all differences <b>directly</b> related to the given one.
+ */
+ private static Set<Diff> internalGetResultingMerges(Diff diff, IMerger.Registry mergerRegistry,
+ boolean mergeRightToLeft) {
+ final IMerger merger = mergerRegistry.getHighestRankingMerger(diff);
+
+ final Set<Diff> directParents;
+ final Set<Diff> directImplications;
+ if (merger instanceof IMerger2) {
+ directParents = ((IMerger2)merger).getDirectMergeDependencies(diff, mergeRightToLeft);
+ directImplications = ((IMerger2)merger).getDirectResultingMerges(diff, mergeRightToLeft);
+ } else {
+ directParents = Collections.emptySet();
+ directImplications = Collections.emptySet();
+ }
+
+ return Sets.newLinkedHashSet(Sets.union(directParents, directImplications));
+ }
+
+ /**
+ * Retrieves the set of all diffs that will be rejected if the given <code>diff</code> is merged, either
+ * because of unresolveable conflicts or because of unreachable requirements.
+ *
+ * @param diff
+ * The difference for which we seek all opposite ones.
+ * @param mergerRegistry
+ * The {@link IMerger.Registry merger registry} currently in use.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return The set of all diffs that will be rejected if the given <code>diff</code> is merged in the
+ * given direction.
+ */
+ public static Set<Diff> getAllResultingRejections(Diff diff, IMerger.Registry mergerRegistry,
+ boolean mergeRightToLeft) {
+ final Set<Diff> resultingRejections = new LinkedHashSet<Diff>();
+
+ final Set<Diff> allResultingMerges = getAllResultingMerges(diff, mergerRegistry, mergeRightToLeft);
+ for (Diff resulting : allResultingMerges) {
+ Set<Diff> rejections = internalGetResultingRejections(resulting, mergerRegistry, mergeRightToLeft);
+ Set<Diff> difference = Sets.difference(rejections, resultingRejections);
+ while (!difference.isEmpty()) {
+ final Set<Diff> newRejections = new LinkedHashSet<Diff>(difference);
+ resultingRejections.addAll(newRejections);
+ rejections = new LinkedHashSet<Diff>();
+ for (Diff rejected : newRejections) {
+ final IMerger merger = mergerRegistry.getHighestRankingMerger(diff);
+ if (merger instanceof IMerger2) {
+ rejections.addAll(((IMerger2)merger).getDirectMergeDependencies(rejected,
+ mergeRightToLeft));
+ rejections.addAll(((IMerger2)merger).getDirectResultingMerges(rejected,
+ mergeRightToLeft));
+ }
+ }
+ difference = Sets.difference(rejections, resultingRejections);
+ }
+ }
+
+ return resultingRejections;
+ }
+
+ /**
+ * Returns the set of differences directly related to <code>diff</code> that will be rejected if it is
+ * merged.
+ *
+ * @param diff
+ * The difference for which we seek all opposite ones.
+ * @param mergerRegistry
+ * The {@link IMerger.Registry merger registry} currently in use.
+ * @param mergeRightToLeft
+ * The direction in which we're considering a merge.
+ * @return The set of all directly related differences that will be rejected if <code>diff</code> is
+ * merged in the given direction.
+ */
+ private static Set<Diff> internalGetResultingRejections(Diff diff, IMerger.Registry mergerRegistry,
+ boolean mergeRightToLeft) {
+ final IMerger merger = mergerRegistry.getHighestRankingMerger(diff);
+ if (merger instanceof IMerger2) {
+ return ((IMerger2)merger).getDirectResultingRejections(diff, mergeRightToLeft);
+ }
+ return Collections.emptySet();
+ }
+}

Back to the top