/******************************************************************************* * Copyright (c) 2012, 2017 Obeo and others. * 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 * Philip Langer - bug 521948 *******************************************************************************/ package org.eclipse.emf.compare.command.impl; import com.google.common.collect.ImmutableList; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import java.util.Collection; import java.util.List; import java.util.Map; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.compare.ComparePackage; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.DifferenceState; import org.eclipse.emf.compare.command.ICompareCopyCommand; import org.eclipse.emf.compare.merge.IMerger; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.change.ChangeDescription; import org.eclipse.emf.ecore.change.FeatureChange; import org.eclipse.emf.ecore.change.util.ChangeRecorder; import org.eclipse.emf.edit.command.ChangeCommand; /** * This command can be used to copy a number of diffs (or a single one) in a given direction. * * @author Cedric Notot * @since 3.0 */ public abstract class AbstractCopyCommand extends ChangeCommand implements ICompareCopyCommand { /** The list of differences we are to merge. */ protected final List differences; /** Direction of the merge operation. */ protected final boolean leftToRight; /** Merger registry. */ protected final IMerger.Registry mergerRegistry; /** * Constructs an instance of this command given the list of differences that it needs to merge. * * @param changeRecorder * The change recorder associated to this command. * @param notifiers * The collection of notifiers that will be notified of this command's execution. * @param differences * The list of differences that this command should merge. * @param leftToRight * The direction in which {@code differences} should be merged. * @param mergerRegistry * The registry of mergers. */ public AbstractCopyCommand(ChangeRecorder changeRecorder, Collection notifiers, List differences, boolean leftToRight, IMerger.Registry mergerRegistry) { super(changeRecorder, notifiers); this.differences = ImmutableList.copyOf(differences); this.leftToRight = leftToRight; this.mergerRegistry = mergerRegistry; } /** * {@inheritDoc} * * @see org.eclipse.emf.compare.command.ICompareCopyCommand#isLeftToRight() */ public boolean isLeftToRight() { return leftToRight; } /** * {@inheritDoc} * * @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects() */ @Override public Collection getAffectedObjects() { return differences; } /** * {@inheritDoc} * * @see org.eclipse.emf.common.command.AbstractCommand#canExecute() */ @Override public boolean canExecute() { return super.canExecute() && !differences.isEmpty(); } /** * Returns the state changes to any diffs that this command produced. * * @return the state changes to any diffs that this command produced. */ public Multimap getChangedDiffs() { return getChangedDiffs(getChangeDescription(), differences); } /** * Returns the state changes to any relevant diffs modified in the given change description. * * @param changeDescription * the change description to process. * @param relevantDiffs * the diffs for which we can state changes in the map. * @return the state changes to any relevant diffs modified in the given change description. */ public static Multimap getChangedDiffs(ChangeDescription changeDescription, Collection relevantDiffs) { Multimap ret = LinkedHashMultimap.create(); if (changeDescription != null) { for (Map.Entry> entry : changeDescription.getObjectChanges()) { EObject key = entry.getKey(); if (relevantDiffs.contains(key)) { for (FeatureChange featureChange : entry.getValue()) { if (featureChange.getFeature() == ComparePackage.Literals.DIFF__STATE) { Diff diff = (Diff)key; ret.put(diff.getState(), diff); break; } } } } } return ret; } /** * {@inheritDoc} */ @Override public void dispose() { ChangeDescription changes = getChangeDescription(); if (changes != null) { changes.getObjectsToAttach().clear(); } super.dispose(); } }