blob: 1840be822ec0d07ba5a7c61067a000e330e3a494 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2015 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.rcp.ui.internal.contentmergeviewer.accessor.impl;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.getFirst;
import static org.eclipse.emf.compare.merge.AbstractMerger.isInTerminalState;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.CONTAINMENT_REFERENCE_CHANGE;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ResourceAttachmentChange;
import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.TypeConstants;
import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem;
import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil;
import org.eclipse.emf.compare.rcp.ui.internal.util.ResourceUIUtil;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem;
import org.eclipse.emf.ecore.EObject;
/**
* A specific {@link AbstractStructuralFeatureAccessor} for containment
* {@link org.eclipse.emf.compare.ReferenceChange} objects.
*
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @since 4.0
*/
public class ContainmentReferenceChangeAccessorImpl extends AbstractStructuralFeatureAccessor {
/**
* {@inheritDoc}.
*
* @see org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.AbstractStructuralFeatureAccessor#AbstractStructuralFeatureAccessor(org.eclipse.emf.common.notify.AdapterFactory,
* org.eclipse.emf.compare.Diff,
* org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide)
*/
public ContainmentReferenceChangeAccessorImpl(AdapterFactory adapterFactory, Diff diff,
MergeViewerSide side) {
super(adapterFactory, diff, side);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.AbstractStructuralFeatureAccessor#
* computeDifferences()
*/
@Override
protected ImmutableList<Diff> computeDifferences() {
List<Diff> allDifferences = getComparison().getDifferences();
return ImmutableList.<Diff> copyOf(filter(allDifferences, CONTAINMENT_REFERENCE_CHANGE));
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getInitialItem()
*/
@Override
public IMergeViewerItem getInitialItem() {
Diff initialDiff = getInitialDiff();
EObject diffValue = (EObject)MergeViewerUtil.getDiffValue(initialDiff);
Match match = getComparison().getMatch(diffValue);
if (match == null && isInTerminalState(initialDiff) && MergeViewerSide.ANCESTOR != getSide()) {
match = getMatchWithNullValues(initialDiff.getMatch());
}
if (match != null) {
return new MergeViewerItem.Container(getComparison(), getInitialDiff(), match, getSide(),
getRootAdapterFactory());
}
return null;
}
/**
* After merging a diff which will lead to have an insertion point on both sides, the match associated
* with this diff will be unreacheable because its left and right sides will be null. This method will
* find this match.
*
* @param match
* the match of the merged diff.
* @return the match associated with the given merged diff.
*/
private Match getMatchWithNullValues(Match match) {
for (Match subMatch : match.getSubmatches()) {
if (subMatch.getLeft() == null && subMatch.getRight() == null) {
return subMatch;
}
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getItems()
*/
public ImmutableList<? extends IMergeViewerItem> getItems() {
final ImmutableList.Builder<IMergeViewerItem> ret = ImmutableList.builder();
final Collection<IMergeViewerItem> items = Lists.newArrayList();
final Collection<Match> matches = getComparison().getMatches();
for (Match match : matches) {
MergeViewerItem.Container container = null;
if (ResourceUIUtil.isFragment(match, getSide())) {
IMergeViewerItem item = ResourceUIUtil.createItemForNotLoadedFragmentMatch(match, getSide(),
getComparison(), getRootAdapterFactory());
if (item != null) {
items.add(item);
}
} else if (getSide() != MergeViewerSide.ANCESTOR
|| (getSide() == MergeViewerSide.ANCESTOR && match.getOrigin() != null)) {
ResourceAttachmentChange diff = getFirst(
filter(match.getDifferences(), ResourceAttachmentChange.class), null);
container = new MergeViewerItem.Container(getComparison(), diff, match.getLeft(),
match.getRight(), match.getOrigin(), getSide(), getRootAdapterFactory());
items.add(container);
}
}
final IMergeViewerItem newContainer = ResourceUIUtil.addNewContainerForNotLoadedFragmentMatches(items,
getSide(), getComparison(), getRootAdapterFactory());
if (newContainer != null) {
ret.add(newContainer);
} else {
ret.addAll(items);
}
return ret.build();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType()
*/
@Override
public String getType() {
return TypeConstants.TYPE_ETREE_DIFF;
}
}