/******************************************************************************* * 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; } }