package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl; import com.google.common.collect.Lists; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.eclipse.emf.compare.Conflict; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.Match; import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.ThreeWayComparisonGroupProvider.ConflictsGroupImpl; import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.ConflictNode; import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchNode; import org.eclipse.emf.ecore.EObject; public class ConflictNodeBuilder { private final Conflict conflict; private final ConflictsGroupImpl group; private final Map<Match, MatchNode> matchNodes; public ConflictNodeBuilder(Conflict conflict, ConflictsGroupImpl group) { this.conflict = conflict; this.group = group; matchNodes = new LinkedHashMap<Match, MatchNode>(); } /** * Build the node for the conflict. * * @return The node of the conflict, complete with all its children. */ public ConflictNode buildNode() { ConflictNode conflictNode = group.createConflictNode(conflict); for (Diff diff : conflict.getDifferences()) { Match match = group.getTargetMatch(diff); if (match != null) { MatchNode matchNode = ensureMatchNode(match, conflictNode); group.addDiffNode(matchNode, diff); } } List<Match> nonRootMatches = Lists.newArrayListWithCapacity(matchNodes.size()); outer: for (Match match : matchNodes.keySet()) { EObject container = match.eContainer(); while (container instanceof Match) { if (matchNodes.containsKey(container)) { nonRootMatches.add(match); continue outer; } container = container.eContainer(); } } for (Match match : nonRootMatches) { MatchNode matchNode = matchNodes.get(match); EObject container = match.eContainer(); MatchNode childNode = matchNode; boolean stop = false; while (container instanceof Match && !stop) { MatchNode hierarchyNode; if (matchNodes.containsKey(container)) { hierarchyNode = matchNodes.get(container); stop = true; } else { hierarchyNode = group.createMatchNode((Match)container); matchNodes.put((Match)container, hierarchyNode); } hierarchyNode.addSubMatchNode(childNode); childNode = hierarchyNode; container = container.eContainer(); } } return conflictNode; } private MatchNode ensureMatchNode(Match match, ConflictNode conflictNode) { MatchNode node; if (matchNodes.containsKey(match)) { node = matchNodes.get(match); } else { node = group.createMatchNode(match); conflictNode.addConflictingTree(node); matchNodes.put(match, node); } return node; } }