/** * <copyright> * * Copyright (c) 2010-2016 Thales Global Services S.A.S. * 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: * Thales Global Services S.A.S. - initial API and implementation * * </copyright> */ package org.eclipse.emf.diffmerge.ui.diffuidata.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.ECollections; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.diffmerge.api.IMatch; import org.eclipse.emf.diffmerge.api.Role; import org.eclipse.emf.diffmerge.api.diff.IDifference; import org.eclipse.emf.diffmerge.api.diff.IElementRelativePresence; import org.eclipse.emf.diffmerge.api.diff.IReferenceValuePresence; import org.eclipse.emf.diffmerge.diffdata.EMatch; import org.eclipse.emf.diffmerge.diffdata.EMergeableDifference; import org.eclipse.emf.diffmerge.diffdata.EValuePresence; import org.eclipse.emf.diffmerge.ui.EMFDiffMergeUIPlugin; import org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection; import org.eclipse.emf.diffmerge.ui.diffuidata.DiffuidataPackage; import org.eclipse.emf.diffmerge.ui.diffuidata.MatchAndFeature; import org.eclipse.emf.diffmerge.ui.diffuidata.UidiffdataPackage; import org.eclipse.emf.diffmerge.util.structures.FArrayList; import org.eclipse.emf.diffmerge.util.structures.FOrderedSet; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.impl.EObjectImpl; import org.eclipse.emf.ecore.util.EObjectResolvingEList; import org.eclipse.jface.viewers.TreePath; /** * <!-- begin-user-doc --> * An implementation of the model object '<em><b>Comparison Selection</b></em>'. * <!-- end-user-doc --> * <p> * The following features are implemented: * <ul> * <li>{@link org.eclipse.emf.diffmerge.ui.diffuidata.impl.ComparisonSelectionImpl#getSelectedMatches <em>Selected Matches</em>}</li> * <li>{@link org.eclipse.emf.diffmerge.ui.diffuidata.impl.ComparisonSelectionImpl#getSelectedMatchAndFeature <em>Selected Match And Feature</em>}</li> * <li>{@link org.eclipse.emf.diffmerge.ui.diffuidata.impl.ComparisonSelectionImpl#getSelectedTreePath <em>Selected Tree Path</em>}</li> * <li>{@link org.eclipse.emf.diffmerge.ui.diffuidata.impl.ComparisonSelectionImpl#getSelectedValuePresences <em>Selected Value Presences</em>}</li> * </ul> * </p> * * @generated */ public class ComparisonSelectionImpl extends EObjectImpl implements ComparisonSelection { /** * The cached value of the '{@link #getSelectedMatches() <em>Selected Matches</em>}' reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getSelectedMatches() * @generated * @ordered */ protected EList<EMatch> selectedMatches; /** * The (initially null) set of differences to merge according to this selection * @generated NOT */ private EList<EMergeableDifference> _differences; /** * The (initially null) set of elements concerned with differences to merge * @generated NOT */ private EList<EObject> _concernedElements; /** * The optional role for resolving ambiguities in selected full matches * @generated NOT */ private Role _preferredSide; /** * The cached value of the '{@link #getSelectedMatchAndFeature() <em>Selected Match And Feature</em>}' containment reference. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getSelectedMatchAndFeature() * @generated * @ordered */ protected MatchAndFeature selectedMatchAndFeature; /** * The cached value of the '{@link #getSelectedTreePath() <em>Selected Tree Path</em>}' reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getSelectedTreePath() * @generated * @ordered */ protected EList<EMatch> selectedTreePath; /** * The cached value of the '{@link #getSelectedValuePresences() <em>Selected Value Presences</em>}' reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getSelectedValuePresences() * @generated * @ordered */ protected EList<EValuePresence> selectedValuePresences; /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ protected ComparisonSelectionImpl() { super(); } /** * Constructor * @param selected_p a potentially null object * @param preferredSide_p an optional role for resolving selection ambiguities in full matches * @generated NOT */ public ComparisonSelectionImpl(Object selected_p, Role preferredSide_p) { _preferredSide = preferredSide_p; if (selected_p instanceof EMatch) { getSelectedMatches().add((EMatch)selected_p); } else if (selected_p instanceof MatchAndFeature) { selectedMatchAndFeature = (MatchAndFeature)selected_p; } else if (selected_p instanceof TreePath) { TreePath path = (TreePath)selected_p; for (int i = 0; i < path.getSegmentCount(); i++) { getSelectedTreePath().add((EMatch)path.getSegment(i)); } } else if (selected_p instanceof EValuePresence) { getSelectedValuePresences().add((EValuePresence)selected_p); } else if (selected_p instanceof Collection<?>) { Collection<?> collection = (Collection<?>)selected_p; if (!collection.isEmpty()) { List<EMatch> matches = new ArrayList<EMatch>(); List<EValuePresence> presences = new ArrayList<EValuePresence>(); Iterator<?> it = collection.iterator(); while (it.hasNext()) { Object current = it.next(); if (current instanceof EValuePresence) presences.add((EValuePresence)current); else if (current instanceof EMatch) matches.add((EMatch)current); } if (!presences.isEmpty()) { getSelectedValuePresences().addAll(presences); } else { getSelectedMatches().addAll(matches); } } } } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return DiffuidataPackage.Literals.COMPARISON_SELECTION; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<EMatch> getSelectedMatches() { if (selectedMatches == null) { selectedMatches = new EObjectResolvingEList<EMatch>(EMatch.class, this, DiffuidataPackage.COMPARISON_SELECTION__SELECTED_MATCHES); } return selectedMatches; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public MatchAndFeature getSelectedMatchAndFeature() { return selectedMatchAndFeature; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */ public NotificationChain basicSetSelectedMatchAndFeature(MatchAndFeature newSelectedMatchAndFeature, NotificationChain msgs_p) { NotificationChain msgs = msgs_p; MatchAndFeature oldSelectedMatchAndFeature = selectedMatchAndFeature; selectedMatchAndFeature = newSelectedMatchAndFeature; if (eNotificationRequired()) { ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, UidiffdataPackage.COMPARISON_SELECTION__SELECTED_MATCH_AND_FEATURE, oldSelectedMatchAndFeature, newSelectedMatchAndFeature); if (msgs == null) msgs = notification; else msgs.add(notification); } return msgs; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<EMatch> getSelectedTreePath() { if (selectedTreePath == null) { selectedTreePath = new EObjectResolvingEList<EMatch>(EMatch.class, this, DiffuidataPackage.COMPARISON_SELECTION__SELECTED_TREE_PATH); } return selectedTreePath; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<EValuePresence> getSelectedValuePresences() { if (selectedValuePresences == null) { selectedValuePresences = new EObjectResolvingEList<EValuePresence>(EValuePresence.class, this, DiffuidataPackage.COMPARISON_SELECTION__SELECTED_VALUE_PRESENCES); } return selectedValuePresences; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { switch (featureID) { case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_MATCH_AND_FEATURE: return basicSetSelectedMatchAndFeature(null, msgs); } return super.eInverseRemove(otherEnd, featureID, msgs); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_MATCHES: return getSelectedMatches(); case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_MATCH_AND_FEATURE: return getSelectedMatchAndFeature(); case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_TREE_PATH: return getSelectedTreePath(); case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_VALUE_PRESENCES: return getSelectedValuePresences(); } return super.eGet(featureID, resolve, coreType); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_MATCHES: return selectedMatches != null && !selectedMatches.isEmpty(); case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_MATCH_AND_FEATURE: return selectedMatchAndFeature != null; case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_TREE_PATH: return selectedTreePath != null && !selectedTreePath.isEmpty(); case DiffuidataPackage.COMPARISON_SELECTION__SELECTED_VALUE_PRESENCES: return selectedValuePresences != null && !selectedValuePresences.isEmpty(); } return super.eIsSet(featureID); } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#asDifferencesToMerge() * @generated NOT */ public EList<EMergeableDifference> asDifferencesToMerge() { if (_differences == null) _differences = getDifferencesToMerge(); return ECollections.unmodifiableEList(_differences); } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#asFeature() * @generated NOT */ public EStructuralFeature asFeature() { EStructuralFeature result = null; if (getSelectedMatchAndFeature() != null) { result = getSelectedMatchAndFeature().getFeature(); } else { EValuePresence presence = asValuePresence(); if (presence != null) { if (representAsOwnership(presence)) result = EMFDiffMergeUIPlugin.getDefault().getOwnershipFeature(); else result = presence.getFeature(); } } return result; } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#asMatch() * @generated NOT */ public EMatch asMatch() { EMatch result = null; if (!getSelectedMatches().isEmpty()) { result = getSelectedMatches().get(0); } else if (!getSelectedTreePath().isEmpty()) { result = getSelectedTreePath().get(getSelectedTreePath().size()-1); } else if (getSelectedMatchAndFeature() != null) { result = getSelectedMatchAndFeature().getMatch(); } else if (!getSelectedValuePresences().isEmpty()) { EValuePresence presence = asValuePresence(); if (representAsOwnership(presence)) result = (EMatch)((IReferenceValuePresence)presence).getValueMatch(); else result = presence.getElementMatch(); } return result; } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#asMatches() * @generated NOT */ public EList<EMatch> asMatches() { EList<EMatch> result = ECollections.emptyEList(); if (!getSelectedMatches().isEmpty()) { result = getSelectedMatches(); } else if (!getSelectedValuePresences().isEmpty()) { result = new FOrderedSet<EMatch>(); for (EValuePresence valuePresence : getSelectedValuePresences()) { EMatch match = valuePresence.getElementMatch(); if (match != null) result.add(match); } } else if (getSelectedMatchAndFeature() != null || getSelectedTreePath() != null) { result = new BasicEList<EMatch>(1); EMatch match = asMatch(); if (match != null) result.add(match); } return ECollections.unmodifiableEList(result); } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#asMatchPath() * @generated NOT */ public TreePath asMatchPath() { TreePath result = null; if (!getSelectedTreePath().isEmpty()) result = new TreePath(getSelectedTreePath().toArray()); return result; } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#asValuePresences() * @generated NOT */ public EList<EValuePresence> asValuePresences() { return getSelectedValuePresences(); } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#asValuePresence() * @generated NOT */ public EValuePresence asValuePresence() { EValuePresence result = null; if (!getSelectedValuePresences().isEmpty()) result = getSelectedValuePresences().get(0); return result; } /** * @see org.eclipse.emf.diffmerge.ui.diffuidata.ComparisonSelection#dispose() * @generated NOT */ public void dispose() { if (_concernedElements != null) _concernedElements.clear(); if (_differences != null) _differences.clear(); selectedMatchAndFeature = null; if (selectedMatches != null) selectedMatches.clear(); if (selectedTreePath != null) selectedTreePath.clear(); if (selectedValuePresences != null) selectedValuePresences.clear(); } /** * Return the model elements concerned by this selection * @return a non-null, potentially empty collection * @generated NOT */ private EList<EObject> getConcernedElements() { EList<EObject> result = new FOrderedSet<EObject>(); List<EMatch> matches = asMatches(); if (matches.isEmpty() || _preferredSide == null) { for (EMergeableDifference difference : asDifferencesToMerge()) { if (difference instanceof IElementRelativePresence) { IElementRelativePresence elementDifference = (IElementRelativePresence)difference; IMatch match = elementDifference.getElementMatch(); if (match != null) { EObject element = match.get(elementDifference.getPresenceRole()); result.add(element); } } } } else { for (EMatch match : matches) { EObject element = match.get(_preferredSide); if (element != null) result.add(element); } if (result.isEmpty()) { for (EMatch match : matches) { EObject element = match.get(_preferredSide.opposite()); if (element != null) result.add(element); } } } return result; } /** * Return the differences to merge according to this selection * @return a non-null, potentially empty collection * @generated NOT */ @SuppressWarnings({ "unchecked", "rawtypes" }) private EList<EMergeableDifference> getDifferencesToMerge() { EList<EMergeableDifference> result = new FArrayList<EMergeableDifference>(); if (!asValuePresences().isEmpty()) { result.addAll(asValuePresences()); } else if (!getSelectedMatches().isEmpty()) { for (EMatch match : getSelectedMatches()) { result.addAll((Collection)match.getAllDifferences()); } } else { EValuePresence presence = asValuePresence(); if (presence != null) { // Value presence result.add(presence); } else { IMatch match = asMatch(); EStructuralFeature feature = asFeature(); if (match != null && feature != null) { // All differences of a given feature on a given match if (feature instanceof EAttribute) result.addAll((Collection)match.getAttributeDifferences((EAttribute)feature)); else result.addAll((Collection)match.getReferenceDifferences((EReference)feature)); } else if (match != null) { // All differences on a given match result.addAll((Collection)match.getAllDifferences()); } } } return result; } /** * @see org.eclipse.jface.viewers.IStructuredSelection#getFirstElement() * @generated NOT */ public EObject getFirstElement() { List<EObject> list = toList(); return list.isEmpty()? null: list.get(0); } /** * @see org.eclipse.jface.viewers.ISelection#isEmpty() * @generated NOT */ public boolean isEmpty() { return getSelectedMatches().isEmpty() && getSelectedMatchAndFeature() == null && getSelectedTreePath().isEmpty() && getSelectedValuePresences().isEmpty(); } /** * @see org.eclipse.jface.viewers.IStructuredSelection#iterator() * @generated NOT */ public Iterator<EObject> iterator() { return toList().iterator(); } /** * Return whether the given difference is represented as a virtual "ownership" * (an opposite to a containment value presence) * @param difference_p a potentially null difference * @generated NOT */ private boolean representAsOwnership(IDifference difference_p) { boolean result = false; if (difference_p instanceof IReferenceValuePresence) { IReferenceValuePresence presence = (IReferenceValuePresence)difference_p; EReference ref = presence.getFeature(); result = !presence.isOrder() && ref != null && ref.isContainment(); } return result; } /** * @see org.eclipse.jface.viewers.IStructuredSelection#size() * @generated NOT */ public int size() { return toList().size(); } /** * @see org.eclipse.jface.viewers.IStructuredSelection#toArray() * @generated NOT */ public Object[] toArray() { return toList().toArray(); } /** * @see org.eclipse.jface.viewers.IStructuredSelection#toList() * @generated NOT */ public List<EObject> toList() { if (_concernedElements == null) _concernedElements = getConcernedElements(); return ECollections.unmodifiableEList(_concernedElements); } } //ComparisonSelectionImpl