diff options
23 files changed, 461 insertions, 260 deletions
diff --git a/plugins/org.eclipse.emf.compare.diff/.project b/plugins/org.eclipse.emf.compare.diff/.project index cc4379af5..d3ec6600f 100644 --- a/plugins/org.eclipse.emf.compare.diff/.project +++ b/plugins/org.eclipse.emf.compare.diff/.project @@ -21,12 +21,12 @@ </arguments> </buildCommand> <buildCommand> - <name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name> + <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> <arguments> </arguments> </buildCommand> <buildCommand> - <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> + <name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name> <arguments> </arguments> </buildCommand> @@ -34,7 +34,7 @@ <natures> <nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.pde.PluginNature</nature> - <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature> <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> + <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature> </natures> </projectDescription> diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AbstractCheck.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AbstractCheck.java index b76ac0f43..e84a88a6a 100644 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AbstractCheck.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AbstractCheck.java @@ -16,6 +16,7 @@ import java.util.Iterator; import java.util.List; import org.eclipse.emf.compare.diff.EMFCompareDiffMessages; +import org.eclipse.emf.compare.diff.internal.DiffCollectionsHelper; import org.eclipse.emf.compare.match.metamodel.Match2Elements; import org.eclipse.emf.compare.match.metamodel.Match3Elements; import org.eclipse.emf.compare.match.metamodel.MatchPackage; @@ -49,6 +50,11 @@ public abstract class AbstractCheck { protected final EcoreUtil.CrossReferencer crossReferencer; /** + * utility class to easily matches lists. + */ + protected DiffCollectionsHelper matcherHelper; + + /** * Instantiates the checker given the current crossreferencing members of the diff engine. * * @param referencer @@ -57,6 +63,7 @@ public abstract class AbstractCheck { */ public AbstractCheck(EcoreUtil.CrossReferencer referencer) { crossReferencer = referencer; + matcherHelper = new DiffCollectionsHelper(referencer); } /** @@ -119,8 +126,8 @@ public abstract class AbstractCheck { */ protected final EObject getMatchedEObject(EObject from, int side) throws IllegalArgumentException { if (side != LEFT_OBJECT && side != RIGHT_OBJECT && side != ANCESTOR_OBJECT) { - throw new IllegalArgumentException(EMFCompareDiffMessages - .getString("GenericDiffEngine.IllegalSide")); //$NON-NLS-1$ + throw new IllegalArgumentException( + EMFCompareDiffMessages.getString("GenericDiffEngine.IllegalSide")); //$NON-NLS-1$ } EObject matchedEObject = null; if (crossReferencer != null) { diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AttributesCheck.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AttributesCheck.java index 135da5070..7665e0b9b 100644 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AttributesCheck.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/AttributesCheck.java @@ -14,7 +14,9 @@ package org.eclipse.emf.compare.diff.engine.check; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.eclipse.emf.compare.FactoryException; import org.eclipse.emf.compare.diff.metamodel.AttributeChangeLeftTarget; @@ -29,7 +31,6 @@ import org.eclipse.emf.compare.match.metamodel.Match3Elements; import org.eclipse.emf.compare.util.EFactory; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; @@ -127,23 +128,7 @@ public class AttributesCheck extends AbstractCheck { * @return <code>true</code> if the <code>left</code> value is distinct from the <code>right</code> value. */ protected boolean areDistinctValues(Object left, Object right) { - final boolean distinct; - if (left instanceof EEnumLiteral && right instanceof EEnumLiteral) { - final StringBuilder value1 = new StringBuilder(); - value1.append(((EEnumLiteral)left).getLiteral()).append(((EEnumLiteral)left).getValue()); - final StringBuilder value2 = new StringBuilder(); - value2.append(((EEnumLiteral)right).getLiteral()).append(((EEnumLiteral)right).getValue()); - distinct = !value1.toString().equals(value2.toString()); - } else if (left instanceof EObject && right instanceof EObject) { - // [248442] This will handle FeatureMapEntries detection - distinct = left != getMatchedEObject((EObject)right); - } else if (left != null && left.getClass().isArray()) { - // [299641] compare arrays by their content instead of instance equality - distinct = areDistinctArrays(left, right); - } else { - distinct = left != null && !left.equals(right) || left == null && left != right; - } - return distinct; + return matcherHelper.areDistinctValues(left, right); } /** @@ -222,8 +207,8 @@ public class AttributesCheck extends AbstractCheck { if (attribute.isMany()) { final List<Object> leftValue = convertFeatureMapList(EFactory.eGetAsList( mapping.getLeftElement(), attributeName)); - final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList(mapping - .getRightElement(), attributeName)); + final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList( + mapping.getRightElement(), attributeName)); if (leftValue.size() != rightValue.size()) { distinct = true; @@ -249,8 +234,8 @@ public class AttributesCheck extends AbstractCheck { } if (distinct) { - createNonConflictingAttributeChange(root, attribute, mapping.getLeftElement(), mapping - .getRightElement()); + createNonConflictingAttributeChange(root, attribute, mapping.getLeftElement(), + mapping.getRightElement()); } } @@ -279,10 +264,10 @@ public class AttributesCheck extends AbstractCheck { if (attribute.isMany()) { final List<Object> leftValue = convertFeatureMapList(EFactory.eGetAsList( mapping.getLeftElement(), attributeName)); - final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList(mapping - .getRightElement(), attributeName)); - final List<Object> ancestorValue = convertFeatureMapList(EFactory.eGetAsList(mapping - .getOriginElement(), attributeName)); + final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList( + mapping.getRightElement(), attributeName)); + final List<Object> ancestorValue = convertFeatureMapList(EFactory.eGetAsList( + mapping.getOriginElement(), attributeName)); for (Object right : rightValue) { rightDistinctFromOrigin = !attributeListContains(ancestorValue, right); @@ -314,8 +299,8 @@ public class AttributesCheck extends AbstractCheck { // non conflicting change if (leftDistinctFromOrigin && !rightDistinctFromOrigin) { - createNonConflictingAttributeChange(root, attribute, mapping.getLeftElement(), mapping - .getRightElement()); + createNonConflictingAttributeChange(root, attribute, mapping.getLeftElement(), + mapping.getRightElement()); // only latest from head has changed } else if (rightDistinctFromOrigin && !leftDistinctFromOrigin) { createRemoteAttributeChange(root, attribute, mapping); @@ -373,10 +358,10 @@ public class AttributesCheck extends AbstractCheck { } else { final List<Object> leftValue = convertFeatureMapList(EFactory.eGetAsList( mapping.getLeftElement(), attribute.getName())); - final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList(mapping - .getRightElement(), attribute.getName())); - final List<Object> ancestorValue = convertFeatureMapList(EFactory.eGetAsList(mapping - .getOriginElement(), attribute.getName())); + final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList( + mapping.getRightElement(), attribute.getName())); + final List<Object> ancestorValue = convertFeatureMapList(EFactory.eGetAsList( + mapping.getOriginElement(), attribute.getName())); for (final Object aValue : leftValue) { if (!attributeListContains(rightValue, aValue)) { @@ -426,8 +411,8 @@ public class AttributesCheck extends AbstractCheck { // We'll use this diffGroup to make use of #createNonConflictingAttributeChange(DiffGroup, EAttribute, // EObject, EObject) final DiffGroup dummyGroup = DiffFactory.eINSTANCE.createDiffGroup(); - createNonConflictingAttributeChange(dummyGroup, attribute, mapping.getLeftElement(), mapping - .getRightElement()); + createNonConflictingAttributeChange(dummyGroup, attribute, mapping.getLeftElement(), + mapping.getRightElement()); if (dummyGroup.getSubDiffElements().size() > 0) { final ConflictingDiffElement conflictingDiff = DiffFactory.eINSTANCE @@ -460,12 +445,17 @@ public class AttributesCheck extends AbstractCheck { private void createNonConflictingAttributeChange(DiffGroup root, EAttribute attribute, EObject leftElement, EObject rightElement) throws FactoryException { if (attribute.isMany()) { - final List<Object> leftValue = convertFeatureMapList(EFactory.eGetAsList(leftElement, attribute - .getName())); - final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList(rightElement, attribute - .getName())); - for (final Object aValue : leftValue) { - if (!attributeListContains(rightValue, aValue)) { + final List<Object> rightValues = convertFeatureMapList(EFactory.eGetAsList(rightElement, + attribute.getName())); + final List<Object> leftValues = convertFeatureMapList(EFactory.eGetAsList(leftElement, + attribute.getName())); + + final Set<Object> uniqueLeftValues = new LinkedHashSet(leftValues); + final Set<Object> uniqueRightValues = new LinkedHashSet(rightValues); + + for (final Object aValue : uniqueLeftValues) { + for (int i = 0; i < matcherHelper.getNumberOfMissingOccurrence(leftValues, rightValues, + aValue); i++) { final AttributeChangeLeftTarget operation = DiffFactory.eINSTANCE .createAttributeChangeLeftTarget(); operation.setAttribute(attribute); @@ -474,9 +464,11 @@ public class AttributesCheck extends AbstractCheck { operation.setLeftTarget(aValue); root.getSubDiffElements().add(operation); } + } - for (final Object aValue : rightValue) { - if (!attributeListContains(leftValue, aValue)) { + for (final Object aValue : uniqueRightValues) { + for (int i = 0; i < matcherHelper.getNumberOfMissingOccurrence(rightValues, leftValues, + aValue); i++) { final AttributeChangeRightTarget operation = DiffFactory.eINSTANCE .createAttributeChangeRightTarget(); operation.setAttribute(attribute); @@ -485,6 +477,7 @@ public class AttributesCheck extends AbstractCheck { operation.setRightTarget(aValue); root.getSubDiffElements().add(operation); } + } } else { final UpdateAttribute operation = DiffFactory.eINSTANCE.createUpdateAttribute(); @@ -515,8 +508,8 @@ public class AttributesCheck extends AbstractCheck { if (attribute.isMany()) { final List<Object> leftValue = convertFeatureMapList(EFactory.eGetAsList( mapping.getLeftElement(), attribute.getName())); - final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList(mapping - .getRightElement(), attribute.getName())); + final List<Object> rightValue = convertFeatureMapList(EFactory.eGetAsList( + mapping.getRightElement(), attribute.getName())); for (final Object aValue : leftValue) { // if the value is present in the right (latest) but not in the // left (working copy), it's been removed remotely diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/ReferencesCheck.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/ReferencesCheck.java index 55e1f9458..d72f558d4 100644 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/ReferencesCheck.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/engine/check/ReferencesCheck.java @@ -133,10 +133,10 @@ public class ReferencesCheck extends AbstractCheck { * We'll need to compute the added and removed reference values from the cross referencing of * unmatched elements as they haven't been processed yet. */ - final List<EObject> leftElementReferences = new ArrayList<EObject>((List<EObject>)EFactory - .eGetAsList(mapping.getLeftElement(), reference.getName())); - final List<EObject> rightElementReferences = new ArrayList<EObject>((List<EObject>)EFactory - .eGetAsList(mapping.getRightElement(), reference.getName())); + final List<EObject> leftElementReferences = new ArrayList<EObject>( + (List<EObject>)EFactory.eGetAsList(mapping.getLeftElement(), reference.getName())); + final List<EObject> rightElementReferences = new ArrayList<EObject>( + (List<EObject>)EFactory.eGetAsList(mapping.getRightElement(), reference.getName())); final List<Integer> removedIndices = new ArrayList<Integer>(); // Purge "left" list of all reference values that have been added to it for (EObject leftValue : new ArrayList<EObject>(leftElementReferences)) { @@ -205,10 +205,10 @@ public class ReferencesCheck extends AbstractCheck { protected void checkReferenceOrderChange(DiffGroup root, EReference reference, EObject leftElement, EObject rightElement, List<ReferenceChangeLeftTarget> addedReferences, List<ReferenceChangeRightTarget> removedReferences) throws FactoryException { - final List<EObject> leftElementReferences = new ArrayList<EObject>((List<EObject>)EFactory - .eGetAsList(leftElement, reference.getName())); - final List<EObject> rightElementReferences = new ArrayList<EObject>((List<EObject>)EFactory - .eGetAsList(rightElement, reference.getName())); + final List<EObject> leftElementReferences = new ArrayList<EObject>( + (List<EObject>)EFactory.eGetAsList(leftElement, reference.getName())); + final List<EObject> rightElementReferences = new ArrayList<EObject>( + (List<EObject>)EFactory.eGetAsList(rightElement, reference.getName())); final List<Integer> removedIndices = new ArrayList<Integer>(removedReferences.size()); // Purge "left" list of all reference values that have been added to it for (final ReferenceChangeLeftTarget added : addedReferences) { @@ -265,8 +265,8 @@ public class ReferencesCheck extends AbstractCheck { */ protected void checkReferenceUpdates(DiffGroup root, Match2Elements mapping, EReference reference) throws FactoryException { - createNonConflictingReferencesUpdate(root, reference, mapping.getLeftElement(), mapping - .getRightElement()); + createNonConflictingReferencesUpdate(root, reference, mapping.getLeftElement(), + mapping.getRightElement()); } /** @@ -285,12 +285,12 @@ public class ReferencesCheck extends AbstractCheck { protected void checkReferenceUpdates(DiffGroup root, Match3Elements mapping, EReference reference) throws FactoryException { final String referenceName = reference.getName(); - final List<Object> leftReferences = convertFeatureMapList(EFactory.eGetAsList(mapping - .getLeftElement(), referenceName)); - final List<Object> rightReferences = convertFeatureMapList(EFactory.eGetAsList(mapping - .getRightElement(), referenceName)); - final List<Object> ancestorReferences = convertFeatureMapList(EFactory.eGetAsList(mapping - .getOriginElement(), referenceName)); + final List<Object> leftReferences = convertFeatureMapList(EFactory.eGetAsList( + mapping.getLeftElement(), referenceName)); + final List<Object> rightReferences = convertFeatureMapList(EFactory.eGetAsList( + mapping.getRightElement(), referenceName)); + final List<Object> ancestorReferences = convertFeatureMapList(EFactory.eGetAsList( + mapping.getOriginElement(), referenceName)); // Checks if there're conflicts if (isConflictual(reference, leftReferences, rightReferences, ancestorReferences)) { @@ -345,8 +345,8 @@ public class ReferencesCheck extends AbstractCheck { } // Check for references order changes if (reference.isOrdered()) { - checkReferenceOrderChange(root, reference, mapping.getLeftElement(), mapping - .getRightElement(), addedReferencesDiffs, removedReferencesDiffs); + checkReferenceOrderChange(root, reference, mapping.getLeftElement(), + mapping.getRightElement(), addedReferencesDiffs, removedReferencesDiffs); } } @@ -462,8 +462,8 @@ public class ReferencesCheck extends AbstractCheck { // We'll use this diffGroup to make use of #createNonConflictingAttributeChange(DiffGroup, EAttribute, // EObject, EObject) final DiffGroup dummyGroup = DiffFactory.eINSTANCE.createDiffGroup(); - createNonConflictingReferencesUpdate(dummyGroup, reference, mapping.getLeftElement(), mapping - .getRightElement()); + createNonConflictingReferencesUpdate(dummyGroup, reference, mapping.getLeftElement(), + mapping.getRightElement()); if (dummyGroup.getSubDiffElements().size() > 0) { final ConflictingDiffElement conflictingDiff = DiffFactory.eINSTANCE @@ -586,8 +586,8 @@ public class ReferencesCheck extends AbstractCheck { // value since this added value itself has no match. createDiff = true; } else { - final double uriSimilarity = ResourceSimilarity.computeURISimilarity(EcoreUtil - .getURI(addedValue), EcoreUtil.getURI(deletedValue)); + final double uriSimilarity = ResourceSimilarity.computeURISimilarity( + EcoreUtil.getURI(addedValue), EcoreUtil.getURI(deletedValue)); if (uriSimilarity < similarReferenceURIThreshold) { createDiff = true; } @@ -885,12 +885,12 @@ public class ReferencesCheck extends AbstractCheck { List<EObject> remoteAddedReferences, List<EObject> remoteDeletedReferences) throws FactoryException { final String referenceName = reference.getName(); - final List<Object> leftReferences = convertFeatureMapList(EFactory.eGetAsList(mapping - .getLeftElement(), referenceName)); - final List<Object> rightReferences = convertFeatureMapList(EFactory.eGetAsList(mapping - .getRightElement(), referenceName)); - final List<Object> ancestorReferences = convertFeatureMapList(EFactory.eGetAsList(mapping - .getOriginElement(), referenceName)); + final List<Object> leftReferences = convertFeatureMapList(EFactory.eGetAsList( + mapping.getLeftElement(), referenceName)); + final List<Object> rightReferences = convertFeatureMapList(EFactory.eGetAsList( + mapping.getRightElement(), referenceName)); + final List<Object> ancestorReferences = convertFeatureMapList(EFactory.eGetAsList( + mapping.getOriginElement(), referenceName)); // populates remotely added references list for (final Object right : rightReferences) { diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/DiffCollectionsHelper.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/DiffCollectionsHelper.java new file mode 100644 index 000000000..67fd7fda1 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/DiffCollectionsHelper.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2011 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.diff.internal; + +import java.lang.reflect.Array; +import java.util.List; + +import org.eclipse.emf.compare.match.metamodel.Match2Elements; +import org.eclipse.emf.compare.match.metamodel.MatchPackage; +import org.eclipse.emf.ecore.EEnumLiteral; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.EcoreUtil.CrossReferencer; + +/** + * Utility class to diff Collection values. + * + * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a> + */ +public class DiffCollectionsHelper { + /** + * the cross referencer used to retrive the matches. + */ + private EcoreUtil.CrossReferencer crossReferencer; + + /** + * Create a new utility to diff collections. + * + * @param referencer + * the cross referencer used to retrieve the matches. + */ + public DiffCollectionsHelper(CrossReferencer referencer) { + this.crossReferencer = referencer; + } + + /** + * Return the number of missing occurrence from tested list comparing with reference list. + * + * @param referenceList + * the reference list. + * @param testedList + * the list to test. + * @param value + * the value to look occurrences for. + * @return the number of "value" occurrences missing in testedList to be like referenceList. + */ + public int getNumberOfMissingOccurrence(List<Object> referenceList, List<Object> testedList, Object value) { + final int expectedOccurrences = getNumberOfOccurrences(referenceList, value); + final int actualOccurrences = getNumberOfOccurrences(testedList, value); + return expectedOccurrences - actualOccurrences; + } + + /** + * Return the number of occurrences in a list. + * + * @param values + * list. + * @param value + * element to look for. + * @return the number of occurrences in it. + */ + private int getNumberOfOccurrences(List<Object> values, Object value) { + int i = 0; + for (Object aValue : values) { + if (!areDistinctValues(aValue, value)) { + i++; + } + } + return i; + } + + /** + * Compare values by equality handling specifics of EMF. + * + * @param left + * object 1. + * @param right + * object 2 + * @return true if both objects are not equals. + */ + public boolean areDistinctValues(Object left, Object right) { + final boolean distinct; + if (left instanceof EEnumLiteral && right instanceof EEnumLiteral) { + final StringBuilder value1 = new StringBuilder(); + value1.append(((EEnumLiteral)left).getLiteral()).append(((EEnumLiteral)left).getValue()); + final StringBuilder value2 = new StringBuilder(); + value2.append(((EEnumLiteral)right).getLiteral()).append(((EEnumLiteral)right).getValue()); + distinct = !value1.toString().equals(value2.toString()); + } else if (left instanceof EObject && right instanceof EObject) { + // [248442] This will handle FeatureMapEntries detection + distinct = left != getMatchedEObject((EObject)right); + } else if (left != null && left.getClass().isArray()) { + // [299641] compare arrays by their content instead of instance equality + distinct = areDistinctArrays(left, right); + } else { + distinct = left != null && !left.equals(right) || left == null && left != right; + } + return distinct; + } + + /** + * Return the left or right matched EObject from the one given. More specifically, this will return the + * left matched element if the given {@link EObject} is the right one, or the right matched element if the + * given {@link EObject} is either the left or the origin one. + * + * @param from + * The original {@link EObject}. + * @return The matched {@link EObject}. + */ + protected final EObject getMatchedEObject(EObject from) { + EObject matchedEObject = null; + if (crossReferencer != null && from != null && crossReferencer.get(from) != null) { + for (final org.eclipse.emf.ecore.EStructuralFeature.Setting setting : crossReferencer.get(from)) { + if (setting.getEObject() instanceof Match2Elements) { + if (setting.getEStructuralFeature().getFeatureID() == MatchPackage.MATCH2_ELEMENTS__LEFT_ELEMENT) { + matchedEObject = ((Match2Elements)setting.getEObject()).getRightElement(); + } else if (setting.getEStructuralFeature().getFeatureID() == MatchPackage.MATCH2_ELEMENTS__RIGHT_ELEMENT) { + matchedEObject = ((Match2Elements)setting.getEObject()).getLeftElement(); + } + } + } + } + return matchedEObject; + } + + /** + * Compares two values as arrays, checking that the length and content of both matches each other. + * + * @param left + * The value of the attribute from the left compare resource. + * @param right + * The value of the attribute from the right compare resource. + * @return <code>true</code> if the <code>left</code> value is distinct from the <code>right</code> value. + */ + private boolean areDistinctArrays(Object left, Object right) { + boolean distinct = false; + // we know left is a non-null array. + if (right == null || !right.getClass().isArray()) { + distinct = true; + } else { + final int leftLength = Array.getLength(left); + final int rightLength = Array.getLength(right); + if (leftLength != rightLength) { + distinct = true; + } else { + for (int i = 0; i < leftLength; i++) { + final Object leftElement = Array.get(left, i); + final Object rightElement = Array.get(right, i); + if (areDistinctValues(leftElement, rightElement)) { + distinct = true; + break; + } + } + } + } + return distinct; + } + +} diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeLeftTargetMerger.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeLeftTargetMerger.java index 20c176bef..401e4bd26 100755 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeLeftTargetMerger.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeLeftTargetMerger.java @@ -66,10 +66,10 @@ public class AttributeChangeLeftTargetMerger extends DefaultMerger { try { int valueIndex = -1; if (attr.isMany()) { - EObject leftElement = theDiff.getLeftElement(); - Object leftValues = leftElement.eGet(attr); + final EObject leftElement = theDiff.getLeftElement(); + final Object leftValues = leftElement.eGet(attr); if (leftValues instanceof List) { - List leftValuesList = (List)leftValues; + final List leftValuesList = (List)leftValues; valueIndex = leftValuesList.indexOf(value); } } diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeRightTargetMerger.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeRightTargetMerger.java index 0db0b3b8a..5a836dc14 100755 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeRightTargetMerger.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/AttributeChangeRightTargetMerger.java @@ -47,10 +47,10 @@ public class AttributeChangeRightTargetMerger extends DefaultMerger { try { int valueIndex = -1; if (attr.isMany()) { - EObject rightElement = theDiff.getRightElement(); - Object rightValues = rightElement.eGet(attr); + final EObject rightElement = theDiff.getRightElement(); + final Object rightValues = rightElement.eGet(attr); if (rightValues instanceof List) { - List rightValuesList = (List)rightValues; + final List rightValuesList = (List)rightValues; valueIndex = rightValuesList.indexOf(value); } } diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeLeftTargetMerger.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeLeftTargetMerger.java index 813353797..1fae85f17 100755 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeLeftTargetMerger.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeLeftTargetMerger.java @@ -70,9 +70,9 @@ public class ModelElementChangeLeftTargetMerger extends DefaultMerger { try { int elementIndex = -1; if (ref.isMany()) { - Object containmentRefVal = element.eContainer().eGet(ref); + final Object containmentRefVal = element.eContainer().eGet(ref); if (containmentRefVal instanceof List) { - List listVal = (List)containmentRefVal; + final List listVal = (List)containmentRefVal; elementIndex = listVal.indexOf(element); } } diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeRightTargetMerger.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeRightTargetMerger.java index 996c4313d..345cc328b 100755 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeRightTargetMerger.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ModelElementChangeRightTargetMerger.java @@ -54,9 +54,9 @@ public class ModelElementChangeRightTargetMerger extends DefaultMerger { try { int elementIndex = -1; if (ref.isMany()) { - Object containmentRefVal = element.eContainer().eGet(ref); + final Object containmentRefVal = element.eContainer().eGet(ref); if (containmentRefVal instanceof List) { - List listVal = (List)containmentRefVal; + final List listVal = (List)containmentRefVal; elementIndex = listVal.indexOf(element); } } @@ -109,10 +109,13 @@ public class ModelElementChangeRightTargetMerger extends DefaultMerger { super.undoInTarget(); } + /** + * {@inheritDoc} + */ @Override public boolean canUndoInTarget() { final ModelElementChangeRightTarget theDiff = (ModelElementChangeRightTarget)this.diff; - boolean isRightElementNotNull = theDiff.getRightElement() != null; + final boolean isRightElementNotNull = theDiff.getRightElement() != null; return isRightElementNotNull; } } diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeLeftTargetMerger.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeLeftTargetMerger.java index b17951076..e0a482abe 100755 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeLeftTargetMerger.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeLeftTargetMerger.java @@ -88,19 +88,19 @@ public class ReferenceChangeLeftTargetMerger extends DefaultMerger { final ReferenceChangeLeftTarget theDiff = (ReferenceChangeLeftTarget)this.diff; // FIXME respect ordering! - EReference reference = theDiff.getReference(); + final EReference reference = theDiff.getReference(); final EObject rightElement = theDiff.getRightElement(); - EObject leftElement = theDiff.getLeftElement(); + final EObject leftElement = theDiff.getLeftElement(); - EObject leftTarget = theDiff.getLeftTarget(); - EObject rightTarget = theDiff.getRightTarget(); + final EObject leftTarget = theDiff.getLeftTarget(); + final EObject rightTarget = theDiff.getRightTarget(); int index = -1; if (reference.isMany()) { - Object leftRefValue = leftElement.eGet(reference); + final Object leftRefValue = leftElement.eGet(reference); if (leftRefValue instanceof List) { - List refLeftValueList = (List)leftRefValue; + final List refLeftValueList = (List)leftRefValue; index = refLeftValueList.indexOf(leftTarget); } } diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeRightTargetMerger.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeRightTargetMerger.java index d9c273e71..f8512fcab 100755 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeRightTargetMerger.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/internal/merge/impl/ReferenceChangeRightTargetMerger.java @@ -53,16 +53,16 @@ public class ReferenceChangeRightTargetMerger extends DefaultMerger { final EObject leftTarget = theDiff.getLeftTarget(); // FIXME respect ordering! - EReference reference = theDiff.getReference(); + final EReference reference = theDiff.getReference(); // ordering handling: int index = -1; if (reference.isMany()) { - EObject rightElement = theDiff.getRightElement(); - Object fightRefValue = rightElement.eGet(reference); + final EObject rightElement = theDiff.getRightElement(); + final Object fightRefValue = rightElement.eGet(reference); if (fightRefValue instanceof List) { - List refRightValueList = (List)fightRefValue; + final List refRightValueList = (List)fightRefValue; index = refRightValueList.indexOf(rightTarget); } } diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/DefaultMerger.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/DefaultMerger.java index 6a00b99f6..5135ac970 100755 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/DefaultMerger.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/DefaultMerger.java @@ -10,12 +10,7 @@ *******************************************************************************/ package org.eclipse.emf.compare.diff.merge; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; - import org.eclipse.emf.compare.diff.merge.service.MergeService; -import org.eclipse.emf.compare.diff.metamodel.ComparisonResourceSnapshot; import org.eclipse.emf.compare.diff.metamodel.ConflictingDiffElement; import org.eclipse.emf.compare.diff.metamodel.DiffElement; import org.eclipse.emf.compare.diff.metamodel.DiffGroup; @@ -29,7 +24,6 @@ import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EGenericType; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; @@ -170,76 +164,76 @@ public class DefaultMerger implements IMerger { * Object to remove all references to. */ protected void removeDanglingReferences(EObject deletedObject) { - EObject root = EcoreUtil.getRootContainer(deletedObject); - if (root instanceof ComparisonResourceSnapshot) { - root = ((ComparisonResourceSnapshot)root).getDiff(); - } - if (root != null) { - // FIXME performance, find a way to cache this referencer - final Resource res = root.eResource(); - final EcoreUtil.CrossReferencer referencer; - if (res != null && res.getResourceSet() != null) { - referencer = new EcoreUtil.CrossReferencer(res.getResourceSet()) { - private static final long serialVersionUID = 616050158241084372L; - - // initializer for this anonymous class - { - crossReference(); - } - - @Override - protected boolean crossReference(EObject eObject, EReference eReference, - EObject crossReferencedEObject) { - if (eReference.isChangeable() && !eReference.isDerived()) - return crossReferencedEObject.eResource() == null; - return false; - } - }; - } else if (res != null) { - referencer = new EcoreUtil.CrossReferencer(res) { - private static final long serialVersionUID = 616050158241084372L; - - // initializer for this anonymous class - { - crossReference(); - } - - @Override - protected boolean crossReference(EObject eObject, EReference eReference, - EObject crossReferencedEObject) { - if (eReference.isChangeable() && !eReference.isDerived()) - return crossReferencedEObject.eResource() == null; - return false; - } - }; - } else { - referencer = new EcoreUtil.CrossReferencer(root) { - private static final long serialVersionUID = 616050158241084372L; - - // initializer for this anonymous class - { - crossReference(); - } - - @Override - protected boolean crossReference(EObject eObject, EReference eReference, - EObject crossReferencedEObject) { - if (eReference.isChangeable() && !eReference.isDerived()) - return crossReferencedEObject.eResource() == null; - return false; - } - }; - } - final Iterator<Map.Entry<EObject, Collection<EStructuralFeature.Setting>>> i = referencer - .entrySet().iterator(); - while (i.hasNext()) { - final Map.Entry<EObject, Collection<EStructuralFeature.Setting>> entry = i.next(); - final Iterator<EStructuralFeature.Setting> j = entry.getValue().iterator(); - while (j.hasNext()) { - EcoreUtil.remove(j.next(), entry.getKey()); - } - } - } + // EObject root = EcoreUtil.getRootContainer(deletedObject); + // if (root instanceof ComparisonResourceSnapshot) { + // root = ((ComparisonResourceSnapshot)root).getDiff(); + // } + // if (root != null) { + // // FIXME performance, find a way to cache this referencer + // final Resource res = root.eResource(); + // final EcoreUtil.CrossReferencer referencer; + // if (res != null && res.getResourceSet() != null) { + // referencer = new EcoreUtil.CrossReferencer(res.getResourceSet()) { + // private static final long serialVersionUID = 616050158241084372L; + // + // // initializer for this anonymous class + // { + // crossReference(); + // } + // + // @Override + // protected boolean crossReference(EObject eObject, EReference eReference, + // EObject crossReferencedEObject) { + // if (eReference.isChangeable() && !eReference.isDerived()) + // return crossReferencedEObject.eResource() == null; + // return false; + // } + // }; + // } else if (res != null) { + // referencer = new EcoreUtil.CrossReferencer(res) { + // private static final long serialVersionUID = 616050158241084372L; + // + // // initializer for this anonymous class + // { + // crossReference(); + // } + // + // @Override + // protected boolean crossReference(EObject eObject, EReference eReference, + // EObject crossReferencedEObject) { + // if (eReference.isChangeable() && !eReference.isDerived()) + // return crossReferencedEObject.eResource() == null; + // return false; + // } + // }; + // } else { + // referencer = new EcoreUtil.CrossReferencer(root) { + // private static final long serialVersionUID = 616050158241084372L; + // + // // initializer for this anonymous class + // { + // crossReference(); + // } + // + // @Override + // protected boolean crossReference(EObject eObject, EReference eReference, + // EObject crossReferencedEObject) { + // if (eReference.isChangeable() && !eReference.isDerived()) + // return crossReferencedEObject.eResource() == null; + // return false; + // } + // }; + // } + // final Iterator<Map.Entry<EObject, Collection<EStructuralFeature.Setting>>> i = referencer + // .entrySet().iterator(); + // while (i.hasNext()) { + // final Map.Entry<EObject, Collection<EStructuralFeature.Setting>> entry = i.next(); + // final Iterator<EStructuralFeature.Setting> j = entry.getValue().iterator(); + // while (j.hasNext()) { + // EcoreUtil.remove(j.next(), entry.getKey()); + // } + // } + // } } /** diff --git a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/EMFCompareEObjectCopier.java b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/EMFCompareEObjectCopier.java index 7e6b08dbb..c1182b73b 100644 --- a/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/EMFCompareEObjectCopier.java +++ b/plugins/org.eclipse.emf.compare.diff/src/org/eclipse/emf/compare/diff/merge/EMFCompareEObjectCopier.java @@ -158,8 +158,8 @@ public class EMFCompareEObjectCopier extends org.eclipse.emf.ecore.util.EcoreUti } if (matchedValue != null) { put(actualValue, matchedValue); - List targetList = (List<Object>)target.eGet(targetReference); - int targetListSize = targetList.size(); + final List targetList = (List<Object>)target.eGet(targetReference); + final int targetListSize = targetList.size(); if (index > -1 && index < targetListSize) { targetList.add(index, matchedValue); } else { diff --git a/plugins/org.eclipse.emf.compare.match/.project b/plugins/org.eclipse.emf.compare.match/.project index 84fac13d4..ff7544f8b 100644 --- a/plugins/org.eclipse.emf.compare.match/.project +++ b/plugins/org.eclipse.emf.compare.match/.project @@ -21,11 +21,6 @@ </arguments> </buildCommand> <buildCommand> - <name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> <arguments> </arguments> @@ -34,7 +29,6 @@ <natures> <nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.pde.PluginNature</nature> - <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature> <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> </natures> </projectDescription> diff --git a/plugins/org.eclipse.emf.compare.match/src/org/eclipse/emf/compare/match/engine/GenericMatchEngine.java b/plugins/org.eclipse.emf.compare.match/src/org/eclipse/emf/compare/match/engine/GenericMatchEngine.java index 821f531da..d7fa499d5 100755 --- a/plugins/org.eclipse.emf.compare.match/src/org/eclipse/emf/compare/match/engine/GenericMatchEngine.java +++ b/plugins/org.eclipse.emf.compare.match/src/org/eclipse/emf/compare/match/engine/GenericMatchEngine.java @@ -359,7 +359,7 @@ public class GenericMatchEngine implements IMatchEngine { * the settings to update. * @param optionMap * the match options. - *@since 1.1 + * @since 1.1 */ protected void updateSettings(MatchSettings settings, Map<String, Object> optionMap) { if (optionMap != null && optionMap.size() > 0) { @@ -406,7 +406,7 @@ public class GenericMatchEngine implements IMatchEngine { * The scope to restrict which content of the left object is processed. * @param rightObject * Right of the two objects to compare. - *@param rightScope + * @param rightScope * The scope to restrict which content of the left object is processed. * @return {@link MatchModel} for these two objects' comparison. */ @@ -486,8 +486,8 @@ public class GenericMatchEngine implements IMatchEngine { startMonitor(monitor, size << 1); // see if scope provider was passed in via option, otherwise create default one - final IMatchScopeProvider scopeProvider = MatchScopeProviderUtil.getScopeProvider(optionMap, leftRoot - .eResource(), rightRoot.eResource(), ancestor.eResource()); + final IMatchScopeProvider scopeProvider = MatchScopeProviderUtil.getScopeProvider(optionMap, + leftRoot.eResource(), rightRoot.eResource(), ancestor.eResource()); final IMatchScope leftScope = scopeProvider.getLeftScope(); final IMatchScope rightScope = scopeProvider.getRightScope(); @@ -495,8 +495,8 @@ public class GenericMatchEngine implements IMatchEngine { if (leftScope.isInScope(leftRoot.eResource()) && rightScope.isInScope(rightRoot.eResource()) && ancestorScope.isInScope(ancestor.eResource())) { - result = doMatch(leftRoot.eResource(), leftScope, rightRoot.eResource(), rightScope, ancestor - .eResource(), ancestorScope, monitor); + result = doMatch(leftRoot.eResource(), leftScope, rightRoot.eResource(), rightScope, + ancestor.eResource(), ancestorScope, monitor); } return result; @@ -653,6 +653,15 @@ public class GenericMatchEngine implements IMatchEngine { result = doMatch(leftResource, leftScope, rightResource, rightScope, ancestorResource, ancestorScope, monitor); } + Set<EObject> alreadyUnmatched = new LinkedHashSet<EObject>(); + for (UnmatchElement unmatched : new LinkedHashSet<UnmatchElement>(result.getUnmatchedElements())) { + if (alreadyUnmatched.contains(unmatched.getElement())) { + EcoreUtil.remove(unmatched); + } else { + alreadyUnmatched.add(unmatched.getElement()); + } + + } return result; } @@ -753,8 +762,8 @@ public class GenericMatchEngine implements IMatchEngine { if (correspondingMatch != null) { final Match3Elements match = MatchFactory.eINSTANCE.createMatch3Elements(); - match.setSimilarity(set3WaySimilarity(nextLeftMatch.getLeftElement(), correspondingMatch - .getLeftElement(), correspondingMatch.getRightElement())); + match.setSimilarity(set3WaySimilarity(nextLeftMatch.getLeftElement(), + correspondingMatch.getLeftElement(), correspondingMatch.getRightElement())); match.setLeftElement(nextLeftMatch.getLeftElement()); match.setRightElement(correspondingMatch.getLeftElement()); match.setOriginElement(correspondingMatch.getRightElement()); @@ -807,8 +816,8 @@ public class GenericMatchEngine implements IMatchEngine { final Iterator<Match2Elements> it = mappings.iterator(); while (it.hasNext()) { final Match2Elements map = it.next(); - final Match2Elements match = recursiveMappings(map.getLeftElement(), list1Scope, map - .getRightElement(), list2Scope, monitor); + final Match2Elements match = recursiveMappings(map.getLeftElement(), list1Scope, + map.getRightElement(), list2Scope, monitor); redirectedAdd(root, SUBMATCH_ELEMENT_NAME, match); } } @@ -924,8 +933,8 @@ public class GenericMatchEngine implements IMatchEngine { checker.init(leftResource, rightResource); monitor.subTask(EMFCompareMatchMessages.getString("DifferencesServices.monitor.roots")); //$NON-NLS-1$ - final List<Match2Elements> matchedRoots = mapLists(leftContents, rightContents, structuredOptions - .getSearchWindow(), monitor); + final List<Match2Elements> matchedRoots = mapLists(leftContents, rightContents, + structuredOptions.getSearchWindow(), monitor); stillToFindFromModel1.clear(); stillToFindFromModel2.clear(); final List<EObject> unmatchedLeftRoots = new ArrayList<EObject>(leftContents); @@ -1059,10 +1068,10 @@ public class GenericMatchEngine implements IMatchEngine { final List<Match2Elements> rightExternal2WayMappings = new ArrayList<Match2Elements>( externalRefMappings); - final List<MatchElement> root1MatchedElements = new ArrayList<MatchElement>(root1AncestorMatch - .getMatchedElements()); - final List<MatchElement> root2MatchedElements = new ArrayList<MatchElement>(root2AncestorMatch - .getMatchedElements()); + final List<MatchElement> root1MatchedElements = new ArrayList<MatchElement>( + root1AncestorMatch.getMatchedElements()); + final List<MatchElement> root2MatchedElements = new ArrayList<MatchElement>( + root2AncestorMatch.getMatchedElements()); // populates the unmatched elements list for later use // There cannot be any conflicts on those, as neither has an ancestor @@ -1079,8 +1088,8 @@ public class GenericMatchEngine implements IMatchEngine { final Match2Elements root1Match = (Match2Elements)root1MatchedElements.get(0); final Match2Elements root2Match = (Match2Elements)root2MatchedElements.get(0); - subMatchRoot.setSimilarity(set3WaySimilarity(root1Match.getLeftElement(), root2Match - .getLeftElement(), root2Match.getRightElement())); + subMatchRoot.setSimilarity(set3WaySimilarity(root1Match.getLeftElement(), + root2Match.getLeftElement(), root2Match.getRightElement())); subMatchRoot.setLeftElement(root1Match.getLeftElement()); subMatchRoot.setRightElement(root2Match.getLeftElement()); subMatchRoot.setOriginElement(root2Match.getRightElement()); @@ -1232,8 +1241,8 @@ public class GenericMatchEngine implements IMatchEngine { double similarity = 0d; try { - similarity = NameSimilarity.nameSimilarityMetric(NameSimilarity.findName(obj1), NameSimilarity - .findName(obj2)); + similarity = NameSimilarity.nameSimilarityMetric(NameSimilarity.findName(obj1), + NameSimilarity.findName(obj2)); } catch (final FactoryException e) { // fails silently, will return a similarity of 0d } @@ -1256,8 +1265,8 @@ public class GenericMatchEngine implements IMatchEngine { @Deprecated protected double contentSimilarity(EObject obj1, EObject obj2) throws FactoryException { double similarity = 0d; - similarity = NameSimilarity.nameSimilarityMetric(NameSimilarity.contentValue(obj1), NameSimilarity - .contentValue(obj2)); + similarity = NameSimilarity.nameSimilarityMetric(NameSimilarity.contentValue(obj1), + NameSimilarity.contentValue(obj2)); return similarity; } @@ -1356,8 +1365,8 @@ public class GenericMatchEngine implements IMatchEngine { if (match1.getRightElement() == match2.getRightElement()) { final Match3Elements match = MatchFactory.eINSTANCE.createMatch3Elements(); - match.setSimilarity(set3WaySimilarity(match1.getLeftElement(), match2 - .getLeftElement(), match2.getRightElement())); + match.setSimilarity(set3WaySimilarity(match1.getLeftElement(), + match2.getLeftElement(), match2.getRightElement())); match.setLeftElement(match1.getLeftElement()); match.setRightElement(match2.getLeftElement()); match.setOriginElement(match2.getRightElement()); @@ -1611,8 +1620,11 @@ public class GenericMatchEngine implements IMatchEngine { final Match2Elements subMapping = it.next(); // As we know source and target are similars, we call recursive // mappings onto these objects - EFactory.eAdd(mapping, SUBMATCH_ELEMENT_NAME, recursiveMappings(subMapping.getLeftElement(), - current1Scope, subMapping.getRightElement(), current2Scope, monitor)); + EFactory.eAdd( + mapping, + SUBMATCH_ELEMENT_NAME, + recursiveMappings(subMapping.getLeftElement(), current1Scope, + subMapping.getRightElement(), current2Scope, monitor)); } // we also have to match those elements, which are directly referenced but not contained in the diff --git a/plugins/org.eclipse.emf.compare.tests/.project b/plugins/org.eclipse.emf.compare.tests/.project index 69ac4b138..10615551b 100644 --- a/plugins/org.eclipse.emf.compare.tests/.project +++ b/plugins/org.eclipse.emf.compare.tests/.project @@ -20,15 +20,9 @@ <arguments> </arguments> </buildCommand> - <buildCommand> - <name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name> - <arguments> - </arguments> - </buildCommand> </buildSpec> <natures> <nature>org.eclipse.pde.PluginNature</nature> <nature>org.eclipse.jdt.core.javanature</nature> - <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature> </natures> </projectDescription> diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/AllMergeTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/AllMergeTests.java index d871a0f62..6c83384be 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/AllMergeTests.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/AllMergeTests.java @@ -20,6 +20,7 @@ public class AllMergeTests { // $JUnit-BEGIN$ suite.addTestSuite(TestContainmentRemoveMany.class); suite.addTestSuite(TestContainmentOrderAddMany.class); + suite.addTestSuite(DanglingReferenceOnTwoAdds.class); suite.addTestSuite(NonUniqueAttributeOrderTest.class); suite.addTestSuite(NonContainmentOrderTest.class); suite.addTestSuite(ContainmentOrderTest.class); diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/DanglingReferenceOnTwoAdds.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/DanglingReferenceOnTwoAdds.java new file mode 100644 index 000000000..6855323bc --- /dev/null +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/DanglingReferenceOnTwoAdds.java @@ -0,0 +1,57 @@ +package org.eclipse.emf.compare.tests.merge; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.compare.util.ModelUtils; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EcoreFactory; +import org.eclipse.emf.ecore.util.EcoreUtil; + +public class DanglingReferenceOnTwoAdds extends MergeTestBase { + + @Override + public void setUp() throws Exception { + + super.setUp(); + + // We create an EPackage with 4 classes. The fourth one references the first three in its ESuperTypes + // attribute + EcoreFactory factory = EcoreFactory.eINSTANCE; + EPackage p = factory.createEPackage(); + p.setName("TestPackage1"); + EClass class0 = factory.createEClass(); + class0.setName("Class0"); + + p.getEClassifiers().add(class0); + + leftModel = EcoreUtil.copy(p); + URI leftURI = URI.createURI("leftmodel.ecore"); + ModelUtils.attachResource(leftURI, leftModel); + + expectedModel = EcoreUtil.copy(leftModel); + URI expectedURI = URI.createURI("expectedmodel.ecore"); + ModelUtils.attachResource(expectedURI, expectedModel); + + EClass class1 = factory.createEClass(); + class1.setName("Class1"); + EClass class2 = factory.createEClass(); + class2.setName("Class2"); + EClass class3 = factory.createEClass(); + class3.setName("Class3"); + + p.getEClassifiers().add(class1); + p.getEClassifiers().add(class2); + p.getEClassifiers().add(class3); + + EList<EClass> class3SuperTypes = class3.getESuperTypes(); + class3SuperTypes.add(class0); + class3SuperTypes.add(class1); + class3SuperTypes.add(class2); + + rightModel = EcoreUtil.copy(p); + URI rightURI = URI.createURI("rightmodel.ecore"); + ModelUtils.attachResource(rightURI, rightModel); + + } +} diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MergeTestBase.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MergeTestBase.java index d457be941..66298b619 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MergeTestBase.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MergeTestBase.java @@ -25,7 +25,6 @@ import org.eclipse.emf.compare.match.service.MatchService; import org.eclipse.emf.compare.util.ModelUtils; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; /** @@ -84,15 +83,17 @@ public abstract class MergeTestBase extends TestCase { MergeService.merge(differences, isLeftToRight); postMergeHook(isLeftToRight); - boolean mergeOK = EcoreUtil.equals(expectedModel, rightModel); - - if (false == mergeOK) { - - System.err.println("Expected :\n" + ModelUtils.serialize(expectedModel)); - System.err.println("Actual :\n" + ModelUtils.serialize(rightModel)); - - fail(" Merge (leftToRight=" + isLeftToRight + ")failed "); - } + String expected = ModelUtils.serialize(testLeftModel); + String actual = ModelUtils.serialize(testRightModel); + assertEquals(expected, actual); + + // boolean mergeOK = EcoreUtil.equals(expectedModel, rightModel); + // if (false == mergeOK) { + // + // System.err.println("Expected :\n" + expected); + // System.err.println("Actual :\n" + actual); + // fail(" Merge (leftToRight=" + isLeftToRight + ")failed "); + // } } /** diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TestContainmentRemove.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TestContainmentRemove.java index 5df192f0f..613da6656 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TestContainmentRemove.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/TestContainmentRemove.java @@ -62,8 +62,8 @@ public class TestContainmentRemove extends MergeTestBase { EPackage leftPackage = (EPackage)leftModel; EPackage rightPackage = (EPackage)rightModel; - assertNotNull("Left eFactoryInstance is not null ", leftPackage.getEFactoryInstance()); - assertNotNull("Right eFactoryInstance is not null ", rightPackage.getEFactoryInstance()); + assertNotNull("Left eFactoryInstance is null ", leftPackage.getEFactoryInstance()); + assertNotNull("Right eFactoryInstance is null ", rightPackage.getEFactoryInstance()); } } diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java index 5aabce05e..45290c8fa 100755 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java @@ -17,6 +17,7 @@ import junit.framework.TestCase; import junit.framework.TestSuite; import junit.textui.TestRunner; +import org.eclipse.emf.compare.tests.merge.AllMergeTests; import org.eclipse.emf.compare.tests.unit.core.CoreTestSuite; import org.eclipse.emf.compare.tests.unit.diff.DiffTestSuite; import org.eclipse.emf.compare.tests.unit.match.MatchTestSuite; @@ -49,6 +50,7 @@ public class AllTests extends TestCase implements IApplication { final TestSuite suite = new TestSuite("EMF Compare test suite"); suite.addTest(CoreTestSuite.suite()); suite.addTest(MatchTestSuite.suite()); + suite.addTest(AllMergeTests.suite()); // This will be null if memory setting is too low final Test diffSuite = DiffTestSuite.suite(); if (diffSuite != null) @@ -65,7 +67,7 @@ public class AllTests extends TestCase implements IApplication { */ public Object start(IApplicationContext context) throws Exception { TestRunner.run(suite()); - return Arrays.asList(new String[] {"Please see raw test suite output for details."}); //$NON-NLS-1$ + return Arrays.asList(new String[] {"Please see raw test suite output for details." }); //$NON-NLS-1$ } /** diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/unit/diff/ThreeWayDiffTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/unit/diff/ThreeWayDiffTest.java index ae323e808..1c295b04e 100644 --- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/unit/diff/ThreeWayDiffTest.java +++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/unit/diff/ThreeWayDiffTest.java @@ -12,6 +12,7 @@ package org.eclipse.emf.compare.tests.unit.diff; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -23,7 +24,6 @@ import org.eclipse.emf.compare.FactoryException; import org.eclipse.emf.compare.diff.metamodel.DiffElement; import org.eclipse.emf.compare.diff.metamodel.DiffGroup; import org.eclipse.emf.compare.diff.metamodel.DiffModel; -import org.eclipse.emf.compare.diff.metamodel.ModelElementChangeLeftTarget; import org.eclipse.emf.compare.diff.service.DiffService; import org.eclipse.emf.compare.match.MatchOptions; import org.eclipse.emf.compare.match.metamodel.MatchModel; @@ -280,22 +280,10 @@ public class ThreeWayDiffTest extends TestCase { final DiffModel diff = DiffService.doDiff(match, true); assertNotNull("Failed to compute the three models' diff.", diff); - final TreeIterator<EObject> diffIterator = diff.eAllContents(); - int elementCount = 0; - int deletionCount = 0; - while (diffIterator.hasNext()) { - final DiffElement aDiff = (DiffElement)diffIterator.next(); - if (aDiff instanceof ModelElementChangeLeftTarget) { - deletionCount++; - } - if (!(aDiff instanceof DiffGroup)) { - elementCount++; - } - } - + Collection<DiffElement> diffs = diff.getDifferences(); // We're expecting two changes, one of which being a removal - assertEquals("Unexpected count of differences.", 2, elementCount); - assertEquals("Unexpected count of deletions in the DiffModel.", 1, deletionCount); + assertEquals("Unexpected count of differences.", 2, diffs.size()); + // assertEquals("Unexpected count of deletions in the DiffModel.", 1, deletionCount); } /** @@ -322,24 +310,12 @@ public class ThreeWayDiffTest extends TestCase { final DiffModel diff = DiffService.doDiff(match, true); assertNotNull("Failed to compute the three models' diff.", diff); - final TreeIterator<EObject> diffIterator = diff.eAllContents(); - int elementCount = 0; - int additionCount = 0; - while (diffIterator.hasNext()) { - final DiffElement aDiff = (DiffElement)diffIterator.next(); - if (aDiff instanceof ModelElementChangeLeftTarget) { - additionCount++; - } - if (!(aDiff instanceof DiffGroup)) { - elementCount++; - } - } - + Collection<DiffElement> diffs = diff.getDifferences(); String v1 = ModelUtils.serialize(testResource1.getContents().get(0)); String v2 = ModelUtils.serialize(testResource2.getContents().get(0)); // We're expecting two changes, one of which being an addition - assertEquals("Unexpected count of differences.", 2, elementCount); - assertEquals("Unexpected count of additions in the DiffModel.", 1, additionCount); + assertEquals("Unexpected count of differences.", 2, diffs.size()); + // assertEquals("Unexpected count of additions in the DiffModel.", 1, additionCount); } } diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/util/EFactory.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/util/EFactory.java index 86a65173c..80cb4315a 100644 --- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/util/EFactory.java +++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/util/EFactory.java @@ -83,8 +83,8 @@ public final class EFactory { if (arg != null) { final Object manyValue = object.eGet(feature); if (manyValue instanceof BasicEList) { - BasicEList<? super T> basicEList = (BasicEList<? super T>)manyValue; - int listSize = basicEList.size(); + final BasicEList<? super T> basicEList = (BasicEList<? super T>)manyValue; + final int listSize = basicEList.size(); if (elementIndex > -1 && elementIndex < listSize) { basicEList.addUnique(elementIndex, arg); } else { |