Class DefaultDiffEngine

java.lang.Object
org.eclipse.emf.compare.diff.DefaultDiffEngine
All Implemented Interfaces:
IDiffEngine

public class DefaultDiffEngine extends Object implements IDiffEngine
The diff engine is in charge of actually computing the differences between the objects mapped by a Match object.

This default implementation aims at being generic enough to be used for any model, whatever the metamodel. However, specific differences, refinements of differences or even higher level differences might be necessary.

TODO document available extension possibilities.
  • Field Details

    • UNMATCHED_VALUE

      protected static final Object UNMATCHED_VALUE
      We'll use this "placeholder" to differentiate the unmatched elements from the "null" values that attributes can legitimately use.
  • Constructor Details

    • DefaultDiffEngine

      public DefaultDiffEngine()
      Create the diff engine.
    • DefaultDiffEngine

      public DefaultDiffEngine(IDiffProcessor processor)
      Create the diff engine.
      Parameters:
      processor - this instance will be called for each detected difference.
  • Method Details

    • indexOf

      protected <E> int indexOf(Comparison comparison, List<E> list, E element)
      Checks whether the given list contains the given element according to the semantics of IEqualityHelper#matchingValues(Comparison, Object, Object) and returns the index at which it is positioned if applicable.
      Type Parameters:
      E - Type of the input iterable's content.
      Parameters:
      comparison - This will be used in order to retrieve the Match for EObjects when comparing them.
      list - List which content we are to check.
      element - The element we expect to be contained in list.
      Returns:
      The index at which the given list contains element, -1 otherwise.
    • diff

      public void diff(Comparison comparison, Monitor monitor)
      This is the entry point of the differencing process.

      It will complete the input comparison by iterating over the matches it contain, filling in the differences it can detect for each distinct Match.

      Specified by:
      diff in interface IDiffEngine
      Parameters:
      comparison - The comparison this engine is expected to complete.
      monitor - The monitor to report progress or to check for cancellation.
      See Also:
    • checkForDifferences

      protected void checkForDifferences(Match match, Monitor monitor)
      Checks the given Match's sides for potential differences. Will recursively check for differences on submatches.
      Parameters:
      match - The match that is to be checked.
      monitor - The monitor to report progress or to check for cancellation.
    • checkResourceAttachment

      protected void checkResourceAttachment(Match match, Monitor monitor)
      Checks whether the given Match's sides have changed resources. This will only be called for Match elements referencing the root(s) of an EMF Resource.
      Parameters:
      match - The match that is to be checked.
      monitor - The monitor to report progress or to check for cancellation.
    • isRoot

      protected static boolean isRoot(EObject eObj)
      Checks whether the given EObject is a root of its resource or not.
      Parameters:
      eObj - The EObject to check.
      Returns:
      true if this object is a root of its containing resource, false otherwise.
    • computeContainmentDifferences

      protected void computeContainmentDifferences(Match match, EReference reference, boolean checkOrdering)
      Delegates the computation of Differences for a given containment reference according to the type of comparison (two- or three-way), and whether we need to take ordering changes into account.
      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The reference whose values are currently being checked for differences.
      checkOrdering - Whether we need to detect ordering changes or ignore them.
    • computeMultiValuedFeatureDifferences

      protected void computeMultiValuedFeatureDifferences(Match match, EStructuralFeature feature, boolean checkOrdering)
      Delegates the computation of Differences for a given muti-valued feature according to the type of comparison (two- or three-way), and whether we need to take ordering changes into account.
      Parameters:
      match - The match which sides we need to check for potential differences.
      feature - The feature whose values are currently being checked for differences.
      checkOrdering - Whether we need to detect ordering changes or ignore them.
    • computeContainmentDifferencesThreeWay

      protected void computeContainmentDifferencesThreeWay(Match match, EReference reference, boolean checkOrdering)
      Computes the difference between the sides of the given match for the given containment reference.

      This is only meant for three-way comparisons.

      Note that this is no longer used for references which ordering is not considered, so checkOrdering will always be true .

      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The containment reference which values are to be checked.
      checkOrdering - true if we should consider ordering changes on this reference, false otherwise.
    • createContainmentDifferencesNoOrdering

      protected void createContainmentDifferencesNoOrdering(Match match, EReference reference, List<Object> sideValues, DifferenceSource side)
      This will iterate over the given list of values from a containment reference and create the differences that can be detected from it.

      Ordering changes will not be considered at all from this method. Values that exist in both the given list of elements and the origin (either ancestor or right side for two-way comparisons), will only have a Diff if their container or containing reference has changed. If they are still in the same container and reference, then even if they are not in the same position, we will not try and detect an ordering change.

      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The containment reference which values are to be checked.
      sideValues - Value of that reference on the given side.
      side - The side currently being compared.
    • createContainmentDifferences

      protected void createContainmentDifferences(Match match, EReference reference, boolean checkOrdering, List<Object> values, List<Object> lcsWithOrigin, DifferenceSource side)
      Called from computeContainmentDifferencesThreeWay(Match, EReference, boolean) once our LCS have been computed and we know what really changed. It will be used for both the left and right side.
      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The containment reference which values are to be checked.
      checkOrdering - true if we should consider ordering changes on this reference, false otherwise.
      values - Value of that reference on the given side.
      lcsWithOrigin - LCS between the reference values on the given side and the values in origin.
      side - The side currently being compared.
    • matchingContainment

      protected boolean matchingContainment(IEqualityHelper equalityHelper, EObject o1, EObject o2)
      Checks whether the two given EObjects are contained within the same object, under the same reference.
      Parameters:
      equalityHelper - Our current equality helper.
      o1 - First of the two EObjects to compare.
      o2 - Second of the two EObjects to compare.
      Returns:
      true if these two objects are contained within the same container, false otherwise.
    • getMatchIfPresent

      protected static com.google.common.base.Optional<Match> getMatchIfPresent(Comparison comparison, List<Object> list, int index)
      This will be used in order to read the LCS synchronously with the iteration on its target lists' values. This should be used cautiously since it will work on empty lists, null values and out-of-scope objects.
      Parameters:
      comparison - The current comparison.
      list - A list of EObjects. May be empty or contain out-of-scope values.
      index - Index of the object we seek within this list.
      Returns:
      An optional containing the match of the object at the given index... or Optional.absent().
    • getIfPresent

      protected static com.google.common.base.Optional<Object> getIfPresent(List<Object> list, int index)
      This will be used in order to read the LCS synchronously with the iteration on its target lists' values. This should be used cautiously since it will work on empty lists, and null values contained in the list are treated the same as an empty list and considered to be Optional.absent().
      Parameters:
      list - A list of EObjects. May be empty or contain null or out-of-scope values.
      index - Index of the object we seek within this list.
      Returns:
      An optional containing the object at the given index... or Optional.absent().
    • computeContainmentDifferencesTwoWay

      protected void computeContainmentDifferencesTwoWay(Match match, EReference reference, boolean checkOrdering)
      Computes the difference between the sides of the given match for the given containment reference.

      This is only meant for two-way comparisons.

      Note that this is no longer used for references which ordering is not considered, so checkOrdering will always be true .

      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The containment reference which values are to be checked.
      checkOrdering - true if we should consider ordering changes on this reference, false otherwise.
    • computeDifferences

      protected void computeDifferences(Match match, EAttribute attribute, boolean checkOrdering)
      Computes the difference between the sides of the given match for the given attribute.
      Parameters:
      match - The match which sides we need to check for potential differences.
      attribute - The attribute which values are to be checked.
      checkOrdering - true if we should consider ordering changes on this attribute, false otherwise.
    • computeDifferences

      protected void computeDifferences(Match match, EReference reference, boolean checkOrdering)
      Computes the difference between the sides of the given match for the given reference.
      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The reference which values are to be checked.
      checkOrdering - true if we should consider ordering changes on this reference, false otherwise.
    • computeMultiValuedFeatureDifferencesThreeWay

      protected void computeMultiValuedFeatureDifferencesThreeWay(Match match, EStructuralFeature feature, boolean checkOrdering)
      Computes the difference between the sides of the given match for the given multi-valued feature.

      The given feature cannot be a containment reference.

      This is only meant for three-way comparisons.

      Note that this is no longer used for features which ordering is not considered, so checkOrdering will always be true .

      Parameters:
      match - The match which sides we need to check for potential differences.
      feature - The feature which values are to be checked.
      checkOrdering - true if we should consider ordering changes on this feature, false otherwise.
    • createMultiValuedFeatureDifferencesNoOrdering

      protected void createMultiValuedFeatureDifferencesNoOrdering(Match match, EStructuralFeature feature, List<Object> sideValues, List<Object> originValues, DifferenceSource side)
      This will iterate over the given list of values from a multi-valued feature and create the differences that can be detected from it.

      Ordering changes will not be considered at all from this method. Values that exist in both the given list of elements and the origin (either ancestor or right side for two-way comparisons), will never have a Diff even if they are not at the same index in the list of their respective side.

      Parameters:
      match - The match which sides we need to check for potential differences.
      feature - The feature which values are to be checked. Cannot be a containment reference.
      sideValues - Value of that reference on the given side.
      originValues - Value of that reference on the origin side. Could be the common ancestor or the right side in case of two-way comparisons.
      side - The side currently being compared.
    • computeMultiValuedFeatureDifferencesTwoWay

      protected void computeMultiValuedFeatureDifferencesTwoWay(Match match, EStructuralFeature feature, boolean checkOrdering)
      Computes the difference between the sides of the given match for the given multi-valued feature.

      The given feature cannot be a containment reference.

      This is only meant for two-way comparisons.

      Note that this is no longer used for features which ordering is not considered, so checkOrdering will always be true .

      Parameters:
      match - The match which sides we need to check for potential differences.
      feature - The feature which values are to be checked.
      checkOrdering - true if we should consider ordering changes on this feature, false otherwise.
    • computeSingleValuedAttributeDifferences

      protected void computeSingleValuedAttributeDifferences(Match match, EAttribute attribute)
      Computes the difference between the sides of the given match for the given single-valued attribute.
      Parameters:
      match - The match which sides we need to check for potential differences.
      attribute - The attribute which values are to be checked.
    • computeSingleValuedReferenceDifferencesThreeWay

      protected void computeSingleValuedReferenceDifferencesThreeWay(Match match, EReference reference)
      Computes the difference between the sides of the given match for the given single-valued reference.

      The given reference cannot be a containment reference.

      This is only meant for three-way comparisons.

      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The reference which values are to be checked.
    • computeSingleValuedReferenceDifferencesTwoWay

      protected void computeSingleValuedReferenceDifferencesTwoWay(Match match, EReference reference)
      Computes the difference between the sides of the given match for the given single-valued reference.

      The given reference cannot be a containment reference.

      This is only meant for two-way comparisons.

      Parameters:
      match - The match which sides we need to check for potential differences.
      reference - The reference which values are to be checked.
    • createFeatureFilter

      protected FeatureFilter createFeatureFilter()
      This will be used in order to create the FeatureFilter that should be used by this engine to determine the structural features on which it is to try and detect differences.
      Returns:
      The newly created feature filter.
    • featureChange

      protected void featureChange(Match match, EStructuralFeature feature, Object value, DifferenceKind kind, DifferenceSource source)
      Delegates to the diff processor to create the specified feature change.
      Parameters:
      match - The match on which values we detected a diff.
      feature - The exact feature on which a diff was detected.
      value - The value for which we detected a changed.
      kind - The kind of difference to create.
      source - The source from which originates that diff.
    • getDiffProcessor

      protected final IDiffProcessor getDiffProcessor()
      This will return the diff processor that has been created through #createDiffProcessor() for this differencing process.
      Returns:
      The diff processor to notify of difference detections.