/** * <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.api; import java.util.Collection; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.diffmerge.api.diff.IAttributeValuePresence; import org.eclipse.emf.diffmerge.api.diff.IDifference; import org.eclipse.emf.diffmerge.api.diff.IElementPresence; import org.eclipse.emf.diffmerge.api.diff.IReferenceValuePresence; import org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope; import org.eclipse.emf.diffmerge.api.scopes.IFeaturedModelScope; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; /** * A comparison between model scopes. * A comparison, once defined, can be computed using match, diff and merge policies. * After computation, it provides a mapping between the contents of the scopes, * a set of differences based on this mapping and the ability to merge a subset of * those differences according to the merge policy. * If the match policy provided was not suitable to the scopes, then the computed * comparison is not consistent and merge is discouraged. * @see IFeaturedModelScope * @see IMatchPolicy * @see IDiffPolicy * @see IMergePolicy * @see IDifference * @see IComparison#isConsistent() * @author Olivier Constant */ public interface IComparison { /** * Clear this comparison, going back to its state before compute(...) was called */ void clear(); /** * Compute this comparison according to the given policies * Postcondition: if result.isOk() then getLastMergePolicy() != null * @param matchPolicy_p an optional match policy (null stands for default) * @param diffPolicy_p an optional diff policy (null stands for default) * @param mergePolicy_p an optional merge policy (null stands for default) * @param monitor_p an optional progress monitor * @return a non-null status of the execution */ IStatus compute(IMatchPolicy matchPolicy_p, IDiffPolicy diffPolicy_p, IMergePolicy mergePolicy_p, IProgressMonitor monitor_p); /** * Return a tree iterator over matches based on getContentsOf(IMatch, Role) * @see IComparison#getContentsOf(IMatch, Role) * @param role_p a non-null role * @return a non-null iterator */ TreeIterator<IMatch> getAllContents(Role role_p); /** * Return the match for the container of the given match in the given role. * Result is null if and only if there is no container in the corresponding * scope or no element in the role for the given match. * @param match_p a non-null match * @param role_p a non-null role * @return a potentially null match */ IMatch getContainerOf(IMatch match_p, Role role_p); /** * Return the matches for the roots of the TARGET and REFERENCE scopes * @return a non-null, potentially empty, unmodifiable ordered set of matches */ List<IMatch> getContents(); /** * Return the matches for the roots of the scope of the given role * @param role_p a non-null role * @return a non-null, potentially empty, unmodifiable ordered set of matches */ List<IMatch> getContents(Role role_p); /** * Return the matches for the contents of the given match in the TARGET and * REFERENCE roles. Matches from REFERENCE come first. * @param match_p a non-null match * @return a non-null, potentially empty, unmodifiable ordered set of matches */ List<IMatch> getContentsOf(IMatch match_p); /** * Return the matches for the contents of the given match in the given role * @param match_p a non-null match * @param role_p a non-null role * @return a non-null, potentially empty, unmodifiable ordered set of matches */ List<IMatch> getContentsOf(IMatch match_p, Role role_p); /** * Return all differences in the given role. * This operation cannot be assumed to be efficient. * The resulting collection may become obsolete if the comparison is reset. * @param role_p a role which is TARGET or REFERENCE * @return a non-null, unmodifiable list which may contain duplicates if differences * are not low-level, technical differences */ List<IDifference> getDifferences(Role role_p); /** * Return the set of duplicate match IDs for the given role, if any. * If the result is not empty, then it means that the match policy that * was used is not applicable to the scope of the given role. * @see IComparison#isConsistent() * @param role_p a non-null role * @return a non-null, possibly empty collection */ Collection<Object> getDuplicateMatchIDs(Role role_p); /** * Return the last diff policy used by this comparison * @return a possibly null diff policy (non-null if the last compute(...) succeeded) */ IDiffPolicy getLastDiffPolicy(); /** * Return the last match policy used by this comparison * @return a possibly null match policy (non-null if the last compute(...) succeeded) */ IMatchPolicy getLastMatchPolicy(); /** * Return the last merge policy used by this comparison * @return a possibly null merge policy (non-null if the last compute(...) succeeded) */ IMergePolicy getLastMergePolicy(); /** * Return the mapping between the model scopes of this comparison * @return a non-null mapping */ IMapping getMapping(); /** * Return the number of differences as the sum of the number of differences * per mapping entry */ int getNbDifferences(); /** * Return the number of differences which are not related to the containment * tree, i.e., those on attributes and cross references * Class invariant: getNbNoContainmentDifferences() <= getNbDifferences() */ int getNbNoContainmentDifferences(); /** * Return the set of differences which have not been merged. * The resulting collection may become obsolete if the comparison is reset. * @return a non-null, potentially empty, unmodifiable collection */ Collection<IDifference> getRemainingDifferences(); /** * Return the scope for the given role * @param role_p a non-null role * @return a scope which is non-null iff the given role is covered by this comparison */ IFeaturedModelScope getScope(Role role_p); /** * Return whether there are differences which have not been merged. * Class invariant: hasRemainingDifferences() == !getRemainingDifferences().isEmpty() * @return a non-null, potentially empty, unmodifiable collection */ boolean hasRemainingDifferences(); /** * Return whether this comparison was consistently computed, i.e., no duplicate * match ID was encountered during computation. * If false, then consistency of merge operations is not guaranteed. * @see IComparison#getDuplicateMatchIDs(Role) */ boolean isConsistent(); /** * Return whether this comparison is three-way and not two-way, that is, * whether it has an ancestor scope which allows detecting conflicts * between the target and reference scopes */ boolean isThreeWay(); /** * Merge the remaining differences to the given destination role * @param destination_p a role which is TARGET or REFERENCE * @param updateReferences_p whether references of the added elements must be set * @param monitor_p an optional progress monitor (null for no progress monitoring) * @return a non-null, potentially empty, unmodifiable set of the differences * which have actually been merged */ Collection<IDifference> merge(Role destination_p, boolean updateReferences_p, IProgressMonitor monitor_p); /** * Merge the given set of differences to the given destination role * @param differences_p a non-null, potentially empty set of differences * @param destination_p a role which is TARGET or REFERENCE * @param updateReferences_p whether references of the added elements must be set * @param monitor_p an optional progress monitor (null for no progress monitoring) * @return a non-null, potentially empty, unmodifiable set of the differences * which have actually been merged */ Collection<IDifference> merge(Collection<? extends IDifference> differences_p, Role destination_p, boolean updateReferences_p, IProgressMonitor monitor_p); /** * Apply the given merge selector to the comparison * @see IMergeSelector * @param merger_p a non-null merger * @param updateReferences_p whether references of the added elements must be set * @param monitor_p an optional progress monitor (null for no progress monitoring) * @return a non-null, potentially empty, unmodifiable set of the differences * which have actually been merged */ Collection<IDifference> merge(IMergeSelector merger_p, boolean updateReferences_p, IProgressMonitor monitor_p); /** * A comparison with editing features. * All concrete classes implementing IComparison must also implement this interface. */ interface Editable extends IComparison { /** * @see org.eclipse.emf.diffmerge.api.IComparison#getMapping() */ IMapping.Editable getMapping(); /** * @see org.eclipse.emf.diffmerge.api.IComparison#getScope(org.eclipse.emf.diffmerge.api.Role) */ IEditableModelScope getScope(Role role_p); /** * Create and return an attribute value presence with the given characteristics * @param elementMatch_p the non-null match for the element holding the value * @param attribute_p the non-null attribute holding the value * @param value_p the non-null value held * @param presenceRole_p the role in which the value is held: TARGET or REFERENCE * @param isOrder_p whether the value presence is solely due to ordering * @return a non-null attribute value presence */ IAttributeValuePresence newAttributeValuePresence( IMatch elementMatch_p, EAttribute attribute_p, Object value_p, Role presenceRole_p, boolean isOrder_p); /** * Create and return a reference value presence with the given characteristics * @param elementMatch_p the non-null partial match for the element presence * @param ownerMatch_p a potentially null match for the owner of the element * @return a non-null element presence */ IElementPresence newElementPresence(IMatch elementMatch_p, IMatch ownerMatch_p); /** * Create and return a match with the given characteristics * @param targetElement_p an optional element on the TARGET side * @param referenceElement_p an optional element on the REFERENCE side * @param ancestorElement_p an optional element on the ANCESTOR side * @return a non-null match */ IMatch newMatch(EObject targetElement_p, EObject referenceElement_p, EObject ancestorElement_p); /** * Create and return a reference value presence with the given characteristics * @param elementMatch_p the non-null match for the element holding the value * @param reference_p the non-null reference holding the value * @param value_p the value element, which may only be null if valueMatch_p is not null * @param valueMatch_p an optional match, which cannot be null if value_p or reference_p is null * @param presenceRole_p the role in which the value is held: TARGET or REFERENCE * @param isOrder_p whether the value presence is solely due to ordering * @return a non-null reference value presence */ IReferenceValuePresence newReferenceValuePresence( IMatch elementMatch_p, EReference reference_p, EObject value_p, IMatch valueMatch_p, Role presenceRole_p, boolean isOrder_p); } }