Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcletavernie2013-06-18 08:16:24 +0000
committercletavernie2013-06-18 08:16:24 +0000
commit098d8c358b9b62de9cb43e6424bca6ecec506087 (patch)
treea79ae6004374ba16ae62adbda5a88db75dbe0284 /deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff
parente30c5c80eb0d2ee70abf965916c04145d78edfbd (diff)
downloadorg.eclipse.papyrus-098d8c358b9b62de9cb43e6424bca6ecec506087.tar.gz
org.eclipse.papyrus-098d8c358b9b62de9cb43e6424bca6ecec506087.tar.xz
org.eclipse.papyrus-098d8c358b9b62de9cb43e6424bca6ecec506087.zip
Deprecate 1.X integration of EMF Compare for Papyrus 0.10.X
Diffstat (limited to 'deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff')
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/Activator.java70
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/FeaturesCheck.java106
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/IFeaturesCheck.java45
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusAttributesCheck.java128
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusReferencesCheck.java147
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/AbstractFireMergeCommand.java76
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/CopyXMIIDCommand.java111
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffEndCommand.java43
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffStartCommand.java43
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationEndCommand.java52
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationStartCommand.java52
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexCommand.java257
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexRequest.java56
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/PapyrusMergeCommandProvider.java78
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AbstractDefaultMerger.java29
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeLeftTargetTransactionalMerger.java125
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeRightTargetTransactionalMerger.java117
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeOrderChangeTransactionalMerger.java300
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultExtensionTransactionalMerger.java81
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultTransactionalMerger.java724
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DiffGroupTransactionalMerger.java106
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeLeftTargetTransactionalMerger.java229
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeRightTargetTransactionalMerger.java235
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/MoveModelElementTransactionalMerger.java226
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeLeftTargetTransactionalMerger.java274
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeRightTargetTransactionalMerger.java277
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceOrderChangeTransactionalMerger.java128
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateAttributeTransactionalMerger.java101
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateReferenceTransactionalMerger.java164
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/provider/DefaultTransactionalMergerProvider.java83
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/CopyWithReferenceCommand.java72
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareEObjectCopier.java440
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareMap.java104
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusEFactory.java297
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/merge/ITransactionalMerger.java114
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/provider/ITransactionalMergerProvider.java25
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/MergerProviderDescriptor.java222
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeFactory.java292
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeService.java466
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptions.java53
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptionsUtils.java45
-rw-r--r--deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusOptionsAdapter.java93
42 files changed, 6686 insertions, 0 deletions
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/Activator.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/Activator.java
new file mode 100644
index 00000000000..2858c1d669e
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/Activator.java
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff;
+
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.infra.emf.compare.diff"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /** the log helper for this plugin */
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ log = new LogHelper(this);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/FeaturesCheck.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/FeaturesCheck.java
new file mode 100644
index 00000000000..c43c699fadd
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/FeaturesCheck.java
@@ -0,0 +1,106 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.check;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.compare.diff.engine.IMatchManager;
+import org.eclipse.emf.compare.diff.engine.check.AbstractCheck;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.papyrus.infra.emf.compare.diff.utils.PapyrusCompareOptions;
+
+/**
+ *
+ * This checker allow to know if differences on a feature should be ignored or not
+ *
+ */
+public class FeaturesCheck extends AbstractCheck implements IFeaturesCheck {
+
+ /**
+ * The list of the features that should be ignored in the whole diff
+ */
+ private final List<EStructuralFeature> ignoreAll;
+
+ /**
+ * the list of the features that should be ignored for some EObject
+ */
+ private final Map<EStructuralFeature, List<EObject>> ignoreSomeCase;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param manager
+ * @param options
+ */
+ @SuppressWarnings("unchecked")
+ //cast on List and Map
+ public FeaturesCheck(final IMatchManager manager, final Map<String, Object> options) {
+ super(manager);
+
+ if(options != null && options.containsKey(PapyrusCompareOptions.KEY_IGNORE_ALL_CHANGES_ON_FEATURES)) {
+ this.ignoreAll = (List<EStructuralFeature>)options.get(PapyrusCompareOptions.KEY_IGNORE_ALL_CHANGES_ON_FEATURES);
+ } else {
+ this.ignoreAll = Collections.EMPTY_LIST;
+ }
+ if(options != null && options.containsKey(PapyrusCompareOptions.KEY_IGNORE_CHANGES_ON_FEATURES_FOR)) {
+ this.ignoreSomeCase = (Map<EStructuralFeature, List<EObject>>)options.get(PapyrusCompareOptions.KEY_IGNORE_CHANGES_ON_FEATURES_FOR);
+ } else {
+ this.ignoreSomeCase = Collections.EMPTY_MAP;
+ }
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param manager
+ */
+ public FeaturesCheck(final IMatchManager manager) {
+ this(manager, null);
+ }
+
+ /**
+ * This method is used to know if a feature should always be ignored
+ *
+ * @param feature
+ * @return
+ */
+ public boolean shouldBeIgnored(final EStructuralFeature feature) {
+ return this.ignoreAll.contains(feature);
+ }
+
+ /**
+ * This method begins by testing the feature must ALWAYS be ignored using shouldBeIgnored(feature).
+ * If not, we verify is the feature should be ignored in some case, depending on its context
+ *
+ *
+ * @param feature
+ * @param context
+ * @return
+ */
+ public boolean shouldBeIgnored(final EStructuralFeature feature, final EObject context) {
+ if(shouldBeIgnored(feature)) {
+ return true;
+ }
+ final List<EObject> values = this.ignoreSomeCase.get(feature);
+ if(values != null) {
+ return values.contains(context);
+ }
+ return false;
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/IFeaturesCheck.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/IFeaturesCheck.java
new file mode 100644
index 00000000000..7ad0443c4a3
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/IFeaturesCheck.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.check;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ *
+ * This interface allows to define checker enable to ignore differences following the context
+ *
+ */
+public interface IFeaturesCheck {
+
+ /**
+ * return <code>true</code> if the feature should be ignored
+ *
+ * @param feature
+ * @return
+ */
+ public boolean shouldBeIgnored(final EStructuralFeature feature);
+
+ /**
+ * return <code>true</code> if the feature should be ignored in this context
+ *
+ * @param feature
+ * a feature
+ * @param context
+ * the context of this attribute
+ * @return
+ */
+ public boolean shouldBeIgnored(final EStructuralFeature feature, final EObject context);
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusAttributesCheck.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusAttributesCheck.java
new file mode 100644
index 00000000000..5f78f3657ab
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusAttributesCheck.java
@@ -0,0 +1,128 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.check;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.engine.IMatchManager;
+import org.eclipse.emf.compare.diff.engine.check.AttributesCheck;
+import org.eclipse.emf.compare.diff.metamodel.DiffGroup;
+import org.eclipse.emf.compare.match.metamodel.Match2Elements;
+import org.eclipse.emf.compare.match.metamodel.Match3Elements;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+
+public class PapyrusAttributesCheck extends AttributesCheck {
+
+ /**
+ * a checker used to manage diff configuration
+ */
+ private final FeaturesCheck checker;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param matchManager
+ * @param featuresCheck
+ * the checker used to manage diff configuration
+ */
+ public PapyrusAttributesCheck(final IMatchManager matchManager, final FeaturesCheck featuresCheck) {
+ super(matchManager);
+ this.checker = featuresCheck;
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.compare.diff.engine.check.AttributesCheck#shouldBeIgnored(org.eclipse.emf.ecore.EAttribute)
+ *
+ * @param attribute
+ * @return
+ */
+ @Override
+ protected boolean shouldBeIgnored(final EAttribute attribute) {
+ boolean shouldBeIgnored = super.shouldBeIgnored(attribute);
+ return shouldBeIgnored || this.checker.shouldBeIgnored(attribute);
+ }
+
+ /**
+ * return <code>true</code> if the attribute should be ignored in this context
+ *
+ * @param attribute
+ * an attribute
+ * @param context
+ * the context of this attribute
+ * @return
+ */
+ protected boolean shouldBeIgnored(final EAttribute attribute, final EObject context) {
+ return this.checker.shouldBeIgnored(attribute, context);
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.compare.diff.engine.check.AttributesCheck#checkAttributesUpdates(org.eclipse.emf.compare.diff.metamodel.DiffGroup, org.eclipse.emf.compare.match.metamodel.Match2Elements)
+ *
+ * @param root
+ * @param mapping
+ * @throws FactoryException
+ */
+ @Override
+ public void checkAttributesUpdates(DiffGroup root, Match2Elements mapping) throws FactoryException {
+ final EClass eClass = mapping.getLeftElement().eClass();
+
+ final List<EAttribute> eclassAttributes = eClass.getEAllAttributes();
+ // for each feature, compare the value
+ final Iterator<EAttribute> it = eclassAttributes.iterator();
+ while(it.hasNext()) {
+ final EAttribute next = it.next();
+ if(!shouldBeIgnored(next) && !shouldBeIgnored(next, mapping.getLeftElement())) {
+ checkAttributeUpdates(root, mapping, next);
+ }
+ }
+ }
+
+ /**
+ * This will iterate through all the attributes of the <code>mapping</code>'s three elements to check if
+ * any of them has been modified.
+ *
+ * @param root
+ * {@link DiffGroup root} of the {@link DiffElement} to create if one of the attribute has
+ * actually been changed.
+ * @param mapping
+ * This contains the mapping information about the elements we need to check for a move.
+ * @throws FactoryException
+ * Thrown if one of the checks fails.
+ */
+ public void checkAttributesUpdates(DiffGroup root, Match3Elements mapping) throws FactoryException {
+ // Ignores matchElements when they don't have origin (no updates on
+ // these)
+ if(mapping.getOriginElement() == null)
+ return;
+ final EClass eClass = mapping.getOriginElement().eClass();
+
+ final List<EAttribute> eclassAttributes = eClass.getEAllAttributes();
+ // for each feature, compare the value
+ final Iterator<EAttribute> it = eclassAttributes.iterator();
+ while(it.hasNext()) {
+ final EAttribute next = it.next();
+ if(!shouldBeIgnored(next) && !shouldBeIgnored(next, mapping.getOriginElement())) {
+ checkAttributeUpdates(root, mapping, next);
+ }
+ }
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusReferencesCheck.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusReferencesCheck.java
new file mode 100644
index 00000000000..226b2b7b52a
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/check/PapyrusReferencesCheck.java
@@ -0,0 +1,147 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.check;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.engine.IMatchManager;
+import org.eclipse.emf.compare.diff.engine.check.ReferencesCheck;
+import org.eclipse.emf.compare.diff.metamodel.DiffGroup;
+import org.eclipse.emf.compare.match.metamodel.Match2Elements;
+import org.eclipse.emf.compare.match.metamodel.Match3Elements;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+
+/**
+ *
+ * This reference checker allows to ignore differences on features for the comparison
+ *
+ */
+public class PapyrusReferencesCheck extends ReferencesCheck {
+
+ /**
+ * the checker used to take in account the ignored features for the Diff
+ */
+ private final FeaturesCheck checker;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param matchManager
+ * @param checker
+ * the checker used to take in account the ignored features for the Diff
+ */
+ public PapyrusReferencesCheck(final IMatchManager matchManager, final FeaturesCheck checker) {
+ super(matchManager);
+ this.checker = checker;
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.compare.diff.engine.check.ReferencesCheck#shouldBeIgnored(org.eclipse.emf.ecore.EReference)
+ *
+ * @param reference
+ * @return
+ */
+ @Override
+ protected boolean shouldBeIgnored(final EReference reference) {
+ boolean shouldBeIgnored = super.shouldBeIgnored(reference);
+ return shouldBeIgnored || this.checker.shouldBeIgnored(reference);
+ }
+
+ /**
+ * return <code>true</code> if the attribute should be ignored in this context
+ *
+ * @param reference
+ * a reference
+ * @param context
+ * the context of this reference
+ * @return
+ */
+ protected boolean shouldBeIgnored(final EReference reference, final EObject context) {
+ return this.checker.shouldBeIgnored(reference, context);
+ }
+
+ /**
+ * Checks if there's been references updates in the model.<br/>
+ * <p>
+ * A reference is considered updated if its value(s) has been changed (either removal or addition of an element if the reference is multi-valued
+ * or update of a single-valued reference) between the left and the right model.
+ * </p>
+ *
+ * @param root
+ * {@link DiffGroup root} of the {@link DiffElement} to create.
+ * @param mapping
+ * Contains informations about the left and right model elements we have to compare.
+ * @throws FactoryException
+ * Thrown if we cannot fetch the references' values.
+ */
+ public void checkReferencesUpdates(DiffGroup root, Match2Elements mapping) throws FactoryException {
+ final EClass eClass = mapping.getLeftElement().eClass();
+ final List<EReference> eclassReferences = eClass.getEAllReferences();
+
+ final Iterator<EReference> it = eclassReferences.iterator();
+ while(it.hasNext()) {
+ final EReference next = it.next();
+ if(!shouldBeIgnored(next, mapping.getLeftElement())) {
+ if(!shouldBeIgnored(next)) {
+ checkReferenceUpdates(root, mapping, next);
+ } else if(next.isContainment() && next.isOrdered()) {
+ checkContainmentReferenceOrderChange(root, mapping, next);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if there's been references updates in the model.<br/>
+ * <p>
+ * A reference is considered updated if its value(s) has been changed (either removal or addition of an element if the reference is multi-valued
+ * or update of a single-valued reference) between the left and the ancestor model, the right and the ancestor or between the left and the right
+ * model.
+ * </p>
+ *
+ * @param root
+ * {@link DiffGroup root} of the {@link DiffElement} to create.
+ * @param mapping
+ * Contains informations about the left, right and origin model elements we have to compare.
+ * @throws FactoryException
+ * Thrown if we cannot fetch the references' values.
+ */
+ public void checkReferencesUpdates(DiffGroup root, Match3Elements mapping) throws FactoryException {
+ // Ignores matchElements when they don't have origin (no updates on these)
+ if(mapping.getOriginElement() == null)
+ return;
+ final EClass eClass = mapping.getOriginElement().eClass();
+ final List<EReference> eclassReferences = eClass.getEAllReferences();
+
+ final Iterator<EReference> it = eclassReferences.iterator();
+ while(it.hasNext()) {
+ final EReference next = it.next();
+ if(!shouldBeIgnored(next, mapping.getLeftElement())) {
+ if(!shouldBeIgnored(next)) {
+ checkReferenceUpdates(root, mapping, next);
+ } else if(next.isContainment() && next.isOrdered()) {
+ checkContainmentReferenceOrderChange(root, mapping, next);
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/AbstractFireMergeCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/AbstractFireMergeCommand.java
new file mode 100644
index 00000000000..e6fea11c30a
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/AbstractFireMergeCommand.java
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.compare.diff.merge.IMergeListener;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+
+
+public abstract class AbstractFireMergeCommand extends AbstractCommand {
+
+ /**
+ * the list of the listeners
+ */
+ private final List<IMergeListener> listeners;
+
+ /**
+ * a list of the diff element
+ */
+ private final List<DiffElement> diffs;
+
+ private final DiffElement diffElement;
+
+ public AbstractFireMergeCommand(final DiffElement diffElement, final List<IMergeListener> listeners) {
+ this.diffElement = diffElement;
+ this.diffs = Collections.emptyList();
+ this.listeners = new ArrayList<IMergeListener>(listeners);
+ }
+
+ public AbstractFireMergeCommand(final List<DiffElement> diffs, final List<IMergeListener> listeners) {
+ this.diffElement = null;
+ this.diffs = new ArrayList<DiffElement>(diffs);
+ this.listeners = new ArrayList<IMergeListener>(listeners);
+ }
+
+ public boolean canRedo() {
+ return canExecute();
+ }
+
+ public List<IMergeListener> getMergeListeners() {
+ return Collections.unmodifiableList(listeners);
+ }
+
+ public List<DiffElement> getDiffElementsList() {
+ return Collections.unmodifiableList(this.diffs);
+ }
+
+ public DiffElement getDiffElement() {
+ return this.diffElement;
+ }
+
+ @Override
+ protected boolean prepare() {
+ return true;
+ }
+
+ public void redo() {
+ execute();
+
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/CopyXMIIDCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/CopyXMIIDCommand.java
new file mode 100644
index 00000000000..ca2070468a5
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/CopyXMIIDCommand.java
@@ -0,0 +1,111 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+
+/**
+ *
+ * This command allows to copy the XMI_ID from one EObject to another one, only if they are not owned by the same resource
+ *
+ */
+//TODO should be moved in infra.emf plugin when the problem of the saùme resource will be corrected in Papyrus
+public class CopyXMIIDCommand extends AbstractCommand {
+
+ /**
+ * the EObject which provides the XMI_ID
+ */
+ private final EObject source;
+
+ /**
+ * the EObject which receive the XMI_ID
+ */
+ private final EObject target;
+
+ /**
+ * the initial XMI_ID of the target
+ */
+ private String initialID;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param source
+ * the EObject which provides the XMI_ID
+ * @param target
+ * the EObject which receive the XMI_ID
+ */
+ public CopyXMIIDCommand(final EObject source, final EObject target) {
+ this.source = source;
+ this.target = target;
+ this.initialID = null;
+ setLabel("Copy XMI_ID command"); //$NON-NLS-1$
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.common.command.Command#execute()
+ *
+ */
+ public void execute() {
+ final Resource sourceResource = source.eResource();
+ final Resource targetResource = target.eResource();
+ if(sourceResource instanceof XMIResource && targetResource instanceof XMIResource) {
+ if(sourceResource != targetResource) {//see bug 377189: [Nested UML Compare] the merged elements have the same XMI ID
+ final String xmi_id = EMFHelper.getXMIID(this.source);
+ this.initialID = EMFHelper.getXMIID(target);
+ ((XMIResource)this.target.eResource()).setID(this.target, xmi_id);
+ }
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.common.command.Command#redo()
+ *
+ */
+ public void redo() {
+ execute();
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.common.command.AbstractCommand#prepare()
+ *
+ * @return
+ */
+ @Override
+ protected boolean prepare() {
+ return true;
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.common.command.AbstractCommand#undo()
+ *
+ */
+ @Override
+ public void undo() {
+ final Resource targetResource = target.eResource();
+ if(targetResource instanceof XMIResource) {
+ ((XMIResource)this.target.eResource()).setID(this.target, this.initialID);
+ }
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffEndCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffEndCommand.java
new file mode 100644
index 00000000000..8f69d5dc751
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffEndCommand.java
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.diff.merge.IMergeListener;
+import org.eclipse.emf.compare.diff.merge.MergeEvent;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+
+
+public class FireMergeDiffEndCommand extends AbstractFireMergeCommand {
+
+ public FireMergeDiffEndCommand(final DiffElement diffElement, final List<IMergeListener> listeners) {
+ super(diffElement, listeners);
+ }
+
+ public void execute() {
+ List<IMergeListener> listeners = getMergeListeners();
+ if(getDiffElement() != null) {
+ for(IMergeListener current : listeners) {
+ current.mergeDiffStart(new MergeEvent(getDiffElement()));
+ }
+
+ }
+ }
+
+ @Override
+ public void undo() {
+ //TODO?
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffStartCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffStartCommand.java
new file mode 100644
index 00000000000..cbbf8bdc1f1
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeDiffStartCommand.java
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.diff.merge.IMergeListener;
+import org.eclipse.emf.compare.diff.merge.MergeEvent;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+
+
+public class FireMergeDiffStartCommand extends AbstractFireMergeCommand {
+
+ public FireMergeDiffStartCommand(final DiffElement diffElement, final List<IMergeListener> listeners) {
+ super(diffElement, listeners);
+ }
+
+ public void execute() {
+ List<IMergeListener> listeners = getMergeListeners();
+ if(getDiffElement() != null) {
+ for(IMergeListener current : listeners) {
+ current.mergeDiffEnd(new MergeEvent(getDiffElement()));
+ }
+
+ }
+ }
+
+ @Override
+ public void undo() {
+ //TODO?
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationEndCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationEndCommand.java
new file mode 100644
index 00000000000..62efe3df121
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationEndCommand.java
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.diff.merge.IMergeListener;
+import org.eclipse.emf.compare.diff.merge.MergeEvent;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+
+
+public class FireMergeOperationEndCommand extends AbstractFireMergeCommand {
+
+ public FireMergeOperationEndCommand(final DiffElement diffElement, final List<IMergeListener> listeners) {
+ super(diffElement, listeners);
+ }
+
+ public FireMergeOperationEndCommand(final List<DiffElement> diffs, final List<IMergeListener> listeners) {
+ super(diffs, listeners);
+ }
+
+ public void execute() {
+ List<IMergeListener> listeners = getMergeListeners();
+ if(!getDiffElementsList().isEmpty()) {
+ for(IMergeListener current : listeners) {
+ current.mergeOperationEnd(new MergeEvent(getDiffElementsList()));
+ }
+ }
+ if(getDiffElement() != null) {
+ for(IMergeListener current : listeners) {
+ current.mergeOperationEnd(new MergeEvent(getDiffElement()));
+ }
+
+ }
+ }
+
+ @Override
+ public void undo() {
+ //TODO?
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationStartCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationStartCommand.java
new file mode 100644
index 00000000000..76f611bc7a7
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/FireMergeOperationStartCommand.java
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.diff.merge.IMergeListener;
+import org.eclipse.emf.compare.diff.merge.MergeEvent;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+
+
+public class FireMergeOperationStartCommand extends AbstractFireMergeCommand {
+
+ public FireMergeOperationStartCommand(final DiffElement diffElement, final List<IMergeListener> listeners) {
+ super(diffElement, listeners);
+ }
+
+ public FireMergeOperationStartCommand(final List<DiffElement> diffs, final List<IMergeListener> listeners) {
+ super(diffs, listeners);
+ }
+
+ public void execute() {
+ List<IMergeListener> listeners = getMergeListeners();
+ if(!getDiffElementsList().isEmpty()) {
+ for(IMergeListener current : listeners) {
+ current.mergeOperationStart(new MergeEvent(getDiffElementsList()));
+ }
+ }
+ if(getDiffElement() != null) {
+ for(IMergeListener current : listeners) {
+ current.mergeOperationStart(new MergeEvent(getDiffElement()));
+ }
+
+ }
+ }
+
+ @Override
+ public void undo() {
+ //TODO?
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexCommand.java
new file mode 100644
index 00000000000..1150ea6df39
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexCommand.java
@@ -0,0 +1,257 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.type.core.commands.MoveElementsCommand;
+import org.eclipse.gmf.runtime.emf.type.core.internal.l10n.EMFTypeCoreMessages;
+import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest;
+
+//TODO move this class and create it in the service edit
+//TODO : breaks this class into 2 classes : 1 for the move and another one for the reorder?
+public class MoveWithIndexCommand extends MoveElementsCommand {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param request
+ */
+ public MoveWithIndexCommand(final MoveRequest request) {
+ super(request);
+ }
+
+ /**
+ *
+ * @see org.eclipse.gmf.runtime.emf.type.core.commands.MoveElementsCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor,
+ * org.eclipse.core.runtime.IAdaptable)
+ *
+ * @param monitor
+ * @param info
+ * @return
+ * @throws ExecutionException
+ */
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ final int index = getIndex();
+ if(index != -1) {
+ for(Iterator<?> i = getElementsToMove().keySet().iterator(); i.hasNext();) {
+ final EObject element = (EObject)i.next();
+ final EReference feature = getTargetFeature(element);
+ if(feature != null) {
+ if(FeatureMapUtil.isMany(getTargetContainer(), feature)) {
+ if(shouldReorder()) {
+ //we attach the real position to the object
+ attachRealPositionEAdapter(element, index);
+ }
+ final Object value = getTargetContainer().eGet(feature);
+ if(value instanceof List<?>) {
+ final List<?> listValue = (List<?>)value;
+ final int indexMax = listValue.size() - 1;
+ if(indexMax < index) {
+ //we add the element at the end of the list
+ final List values = ((List<?>)getTargetContainer().eGet(feature));
+ values.add(element);
+ if(shouldReorder()) {
+ reorderList(values);
+ }
+ } else {
+ ((List)value).add(index, element);
+ if(shouldReorder()) {
+ reorderList((List)value);
+ }
+ }
+
+ } else {
+ ((Collection)getTargetContainer().eGet(feature)).add(element);
+ if(shouldReorder()) {
+ reorderList((List)((Collection)getTargetContainer().eGet(feature)));
+ }
+ }
+ } else {
+ getTargetContainer().eSet(feature, element);
+ }
+ } else {
+ return CommandResult.newErrorCommandResult(EMFTypeCoreMessages.moveElementsCommand_noTargetFeature);
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ return super.doExecuteWithResult(monitor, info);
+ }
+
+ @Override
+ public boolean canExecute() {
+ super.canExecute();
+ return true;
+ }
+
+ /**
+ *
+ * @return
+ * the index for the move command
+ */
+ protected int getIndex() {
+ IEditCommandRequest req = getRequest();
+ if(req instanceof MoveWithIndexRequest) {
+ return ((MoveWithIndexRequest)req).getIndex();
+ }
+ return -1;
+ }
+
+ /**
+ *
+ * @return
+ * <code>true</code> when the list should be reorderded
+ */
+ protected boolean shouldReorder() {
+ final IEditCommandRequest req = getRequest();
+ boolean shouldReoder = false;
+ if(req instanceof MoveWithIndexRequest) {
+ shouldReoder = ((MoveWithIndexRequest)req).shouldReoder();
+ }
+ return shouldReoder;
+ }
+
+ /**
+ * Duplicate code from EFactory
+ * If we could not merge a given object at its expected position in a list, we'll attach an Adapter to it
+ * in order to "remember" that "expected" position. That will allow us to reorder the list later on if
+ * need be.
+ *
+ * @param object
+ * The object on which to attach an Adapter.
+ * @param expectedPosition
+ * The expected position of <code>object</code> in its list.
+ */
+ private void attachRealPositionEAdapter(final Object object, final int expectedPosition) {
+ if(object instanceof EObject) {
+ ((EObject)object).eAdapters().add(new PositionAdapter(expectedPosition));
+ }
+ }
+
+ /**
+ * Reorders the given list if it contains EObjects associated with a PositionAdapter which are not located
+ * at their expected positions.
+ *
+ * @param list
+ * The list that is to be reordered.
+ * @param <T>
+ * type of the list's elements.
+ */
+ private <T> void reorderList(final List<T> list) {
+ List<T> newList = new ArrayList<T>(list);
+ Collections.sort(newList, new EObjectComparator());
+ for(int i = 0; i < list.size(); i++) {
+ int oldIndex = list.indexOf(newList.get(i));
+ list.add(i, list.remove(oldIndex));
+ }
+ return;
+ }
+
+ /**
+ * duplicate code from Efactory
+ * This adapter will be used to remember the accurate position of an EObject in its target list.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+ private static class PositionAdapter extends AdapterImpl {
+
+ /** The index at which we expect to find this object. */
+ private final int expectedIndex;
+
+ /**
+ * Creates our adapter.
+ *
+ * @param index
+ * The index at which we expect to find this object.
+ */
+ public PositionAdapter(final int index) {
+ this.expectedIndex = index;
+ }
+
+ /**
+ * Returns the index at which we expect to find this object.
+ *
+ * @return The index at which we expect to find this object.
+ */
+ public int getExpectedIndex() {
+ return expectedIndex;
+ }
+ }
+
+ /**
+ *
+ * This class allows to compare EObject using the PositionAdapter.
+ *
+ *
+ */
+ private static class EObjectComparator<T> implements Comparator<T> {
+
+ /**
+ *
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ *
+ * @param o1
+ * @param o2
+ * @return
+ */
+ public int compare(final T o1, final T o2) {
+ if(o1 instanceof EObject && o2 instanceof EObject) {
+ final int position1 = getWantedPosition((EObject)o1);
+ final int position2 = getWantedPosition((EObject)o2);
+ if(position1 != -1 && position2 != -1) {
+ return position1 - position2;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ *
+ * @param obj1
+ * an EObject
+ * @return
+ * the wanted position for this object
+ */
+ private int getWantedPosition(final EObject obj1) {
+ final Iterator<Adapter> adapters = obj1.eAdapters().iterator();
+ int expectedIndex = -1;
+ while(expectedIndex == -1 && adapters.hasNext()) {
+ final Adapter adapter = adapters.next();
+ if(adapter instanceof PositionAdapter) {
+ expectedIndex = ((PositionAdapter)adapter).getExpectedIndex();
+ }
+ }
+ return expectedIndex;
+ }
+
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexRequest.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexRequest.java
new file mode 100644
index 00000000000..64abe2dc988
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/MoveWithIndexRequest.java
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest;
+
+//TODO : move this class
+/**
+ *
+ * Created for EMF-Compare, for MoveModelElementMerger
+ *
+ *
+ */
+public class MoveWithIndexRequest extends MoveRequest {
+
+ /**
+ * the wanted index for the moved element
+ */
+ private final int index;
+
+ /**
+ * indicates if the list should be reordered after the move
+ */
+ private final boolean reorder;
+
+ //TODO : and the other constructor?
+ public MoveWithIndexRequest(final TransactionalEditingDomain editingDomain, final EObject targetContainer, final EReference targetFeature, final EObject elementToMove, final int index, final boolean reorder) {
+ super(editingDomain, targetContainer, targetFeature, elementToMove);
+ this.index = index;
+ this.reorder = reorder;
+ }
+
+
+ public int getIndex() {
+ return this.index;
+ }
+
+ public boolean shouldReoder() {
+ return this.reorder;
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/PapyrusMergeCommandProvider.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/PapyrusMergeCommandProvider.java
new file mode 100644
index 00000000000..b0260226a9f
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/command/PapyrusMergeCommandProvider.java
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.command;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyReferenceRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
+import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
+
+//TODO : try to merge with the PapyrusTableCommandFactory?
+public class PapyrusMergeCommandProvider {
+
+ public static PapyrusMergeCommandProvider INSTANCE = new PapyrusMergeCommandProvider();
+
+ private PapyrusMergeCommandProvider() {
+
+ }
+
+ public Command getDestroyCommand(final TransactionalEditingDomain domain, final EObject element) {
+ final IEditCommandRequest request = new DestroyElementRequest(domain, element, false);
+ return getCommand(element, request);
+ }
+
+ //TODO elementToEdit and targetContainer are the same
+ public Command getMoveCommand(final TransactionalEditingDomain domain, final EObject elementToEdit, final EObject targetContainer, final EReference targetFeature, final EObject elementToMove) {
+ final IEditCommandRequest request = new MoveRequest(domain, targetContainer, targetFeature, elementToMove);
+ return getCommand(elementToEdit, request);
+ }
+
+ public Command getCommand(final EObject elementToEdit, final IEditCommandRequest request) {
+ final IElementEditService provider = ElementEditServiceUtils.getCommandProvider(elementToEdit);
+ if(request instanceof MoveWithIndexRequest) {//TODO remove this test when the move with index will be in the service edit
+ return new GMFtoEMFCommandWrapper(new MoveWithIndexCommand((MoveRequest)request));
+ }
+ if(provider != null) {
+ return new GMFtoEMFCommandWrapper(provider.getEditCommand(request));
+ }
+ return null;
+ }
+
+ public Command getDestroyReferenceCommand(final TransactionalEditingDomain editingDomain, final EObject container, final EReference containingFeature, final EObject referencedObject, final boolean confirmationRequired) {
+ final IEditCommandRequest request = new DestroyReferenceRequest(editingDomain, container, containingFeature, referencedObject, confirmationRequired);
+ return getCommand(container, request);
+ }
+
+ public Command getSetCommand(final TransactionalEditingDomain domain, final EObject element, final EStructuralFeature feature, final Object value) {
+ final IEditCommandRequest request = new SetRequest(domain, element, feature, value);
+ return getCommand(element, request);
+ }
+
+
+ //TODO elementToEdit and targetContainer are the same
+ public Command getMoveWithIndexCommand(final TransactionalEditingDomain domain, final EObject elementToEdit, final EObject targetContainer, final EReference targetFeature, final EObject elementToMove, final int index, final boolean reorder) {
+ final IEditCommandRequest request = new MoveWithIndexRequest(domain, targetContainer, targetFeature, elementToMove, index, reorder);
+ return getCommand(elementToEdit, request);
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AbstractDefaultMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AbstractDefaultMerger.java
new file mode 100644
index 00000000000..b35b092fa0a
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AbstractDefaultMerger.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import org.eclipse.emf.compare.diff.merge.IMerger;
+
+
+public abstract class AbstractDefaultMerger implements IMerger {
+
+ final public void applyInOrigin() {
+ throw new UnsupportedOperationException("This method is not available in a Transactional Compare Editor");
+ }
+
+ final public void undoInTarget() {
+ throw new UnsupportedOperationException("This method is not available in a Transactional Compare Editor");
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeLeftTargetTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeLeftTargetTransactionalMerger.java
new file mode 100644
index 00000000000..377b95f0a25
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeLeftTargetTransactionalMerger.java
@@ -0,0 +1,125 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.EMFComparePlugin;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.metamodel.AttributeChangeLeftTarget;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+
+/**
+ *
+ * Transactional version of the class {@link AttributeChangeLeftTargetMerger}
+ *
+ */
+public class AttributeChangeLeftTargetTransactionalMerger extends DefaultTransactionalMerger {
+
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link AttributeChangeLeftTargetMerger}
+ // *
+ // * {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // *
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final AttributeChangeLeftTarget theDiff = (AttributeChangeLeftTarget)this.diff;
+ // final EObject origin = theDiff.getLeftElement();
+ // final Object value = theDiff.getLeftTarget();
+ // final EAttribute attr = theDiff.getAttribute();
+ // try {
+ // EFactory.eRemove(origin, attr.getName(), value);
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link AttributeChangeLeftTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // *
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final AttributeChangeLeftTarget theDiff = (AttributeChangeLeftTarget)this.diff;
+ // final EObject target = theDiff.getRightElement();
+ // final Object value = theDiff.getLeftTarget();
+ // final EAttribute attr = theDiff.getAttribute();
+ // try {
+ // int valueIndex = -1;
+ // if(attr.isMany()) {
+ // final EObject leftElement = theDiff.getLeftElement();
+ // final Object leftValues = leftElement.eGet(attr);
+ // if(leftValues instanceof List) {
+ // final List leftValuesList = (List)leftValues;
+ // valueIndex = leftValuesList.indexOf(value);
+ // }
+ // }
+ // EFactory.eAdd(target, attr.getName(), value, valueIndex);
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+
+
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final AttributeChangeLeftTarget theDiff = (AttributeChangeLeftTarget)this.diff;
+ final EObject origin = theDiff.getLeftElement();
+ final Object value = theDiff.getLeftTarget();
+ final EAttribute attr = theDiff.getAttribute();
+ try {
+ cmd = PapyrusEFactory.getERemoveCommand(domain, origin, attr.getName(), value);
+ } catch (FactoryException e) {
+ EMFComparePlugin.log(e, true);
+ }
+ return cmd;
+ }
+
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final AttributeChangeLeftTarget theDiff = (AttributeChangeLeftTarget)this.diff;
+ final EObject target = theDiff.getRightElement();
+ final Object value = theDiff.getLeftTarget();
+ final EAttribute attr = theDiff.getAttribute();
+ try {
+ int valueIndex = -1;
+ if(attr.isMany()) {
+ final EObject leftElement = theDiff.getLeftElement();
+ final Object leftValues = leftElement.eGet(attr);
+ if(leftValues instanceof List) {
+ final List<?> leftValuesList = (List<?>)leftValues;
+ valueIndex = leftValuesList.indexOf(value);
+ }
+ }
+ cmd = PapyrusEFactory.getEAddCommand(domain, target, attr.getName(), value, valueIndex);
+ } catch (FactoryException e) {
+ Activator.log.error(e);
+ }
+ return cmd;
+
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeRightTargetTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeRightTargetTransactionalMerger.java
new file mode 100644
index 00000000000..32501ba0853
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeChangeRightTargetTransactionalMerger.java
@@ -0,0 +1,117 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.metamodel.AttributeChangeRightTarget;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+
+/**
+ *
+ * Transactional version of the class {@link AttributeChangeRightTargetMerger}
+ *
+ */
+public class AttributeChangeRightTargetTransactionalMerger extends DefaultTransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link AttributeChangeRightTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final AttributeChangeRightTarget theDiff = (AttributeChangeRightTarget)this.diff;
+ // final EObject origin = theDiff.getLeftElement();
+ // final Object value = theDiff.getRightTarget();
+ // final EAttribute attr = theDiff.getAttribute();
+ // try {
+ // int valueIndex = -1;
+ // if(attr.isMany()) {
+ // final EObject rightElement = theDiff.getRightElement();
+ // final Object rightValues = rightElement.eGet(attr);
+ // if(rightValues instanceof List) {
+ // final List rightValuesList = (List)rightValues;
+ // valueIndex = rightValuesList.indexOf(value);
+ // }
+ // }
+ // EFactory.eAdd(origin, attr.getName(), value, valueIndex);
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link AttributeChangeRightTargetMerger}
+ // *
+ // * {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final AttributeChangeRightTarget theDiff = (AttributeChangeRightTarget)this.diff;
+ // final EObject target = theDiff.getRightElement();
+ // final Object value = theDiff.getRightTarget();
+ // final EAttribute attr = theDiff.getAttribute();
+ // try {
+ // EFactory.eRemove(target, attr.getName(), value);
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final AttributeChangeRightTarget theDiff = (AttributeChangeRightTarget)this.diff;
+ final EObject origin = theDiff.getLeftElement();
+ final Object value = theDiff.getRightTarget();
+ final EAttribute attr = theDiff.getAttribute();
+ try {
+ int valueIndex = -1;
+ if(attr.isMany()) {
+ final EObject rightElement = theDiff.getRightElement();
+ final Object rightValues = rightElement.eGet(attr);
+ if(rightValues instanceof List) {
+ final List<?> rightValuesList = (List<?>)rightValues;
+ valueIndex = rightValuesList.indexOf(value);
+ }
+ }
+ cmd = PapyrusEFactory.getEAddCommand(domain, origin, attr.getName(), value, valueIndex);
+ } catch (FactoryException e) {
+ Activator.log.error(e);
+ }
+ return cmd;
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final AttributeChangeRightTarget theDiff = (AttributeChangeRightTarget)this.diff;
+ final EObject target = theDiff.getRightElement();
+ final Object value = theDiff.getRightTarget();
+ final EAttribute attr = theDiff.getAttribute();
+ try {
+ cmd = PapyrusEFactory.getERemoveCommand(domain, target, attr.getName(), value);
+ } catch (FactoryException e) {
+ Activator.log.error(e);
+ }
+ return cmd;
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeOrderChangeTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeOrderChangeTransactionalMerger.java
new file mode 100644
index 00000000000..51eeb52bb4b
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/AttributeOrderChangeTransactionalMerger.java
@@ -0,0 +1,300 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.diff.internal.merge.impl.AttributeOrderChangeMerger;
+import org.eclipse.emf.compare.diff.metamodel.AttributeOrderChange;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.PapyrusMergeCommandProvider;
+import org.eclipse.papyrus.infra.tools.util.ReflectHelper;
+
+/**
+ *
+ * Transactional version of the class {@link AttributeOrderChangeMerger}
+ *
+ */
+public class AttributeOrderChangeTransactionalMerger extends DefaultTransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link AttributeOrderChangeMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final AttributeOrderChange theDiff = (AttributeOrderChange)this.diff;
+ // final EAttribute attribute = theDiff.getAttribute();
+ // final EObject leftElement = theDiff.getLeftElement();
+ // final EObject rightElement = theDiff.getRightElement();
+ //
+ // final List<Object> leftList = (List<Object>)leftElement.eGet(attribute);
+ // final List<Object> rightList = (List<Object>)rightElement.eGet(attribute);
+ //
+ // /*
+ // * We need to transform the "left" list into the "right" list, modulo missing values. In practical
+ // * terms, this means that we'll simply leave untouched any element that has no match in the "right"
+ // * list (elements that were deleted) while reordering the others in the order they have in the "right"
+ // * list.
+ // */
+ // final List<Object> leftCopy = new ArrayList<Object>(leftList);
+ // final List<Object> result = new ArrayList<Object>(leftList.size());
+ // // Add all unmatched values in the result list
+ // for(int i = 0; i < leftList.size(); i++) {
+ // final Object left = leftList.get(i);
+ //
+ // boolean hasMatch = false;
+ // for(int j = 0; !hasMatch && j < rightList.size(); j++) {
+ // hasMatch = !areDistinctValues(left, rightList.get(j));
+ // }
+ //
+ // if(!hasMatch) {
+ // leftCopy.remove(left);
+ // result.add(left);
+ // }
+ // }
+ // // Then reorder according to the right list's order
+ // for(int i = 0; i < rightList.size(); i++) {
+ // final Object right = rightList.get(i);
+ //
+ // Object leftMatch = null;
+ // for(int j = 0; leftMatch == null && j < leftCopy.size(); j++) {
+ // if(!areDistinctValues(right, leftCopy.get(j))) {
+ // leftMatch = leftCopy.get(j);
+ // }
+ // }
+ //
+ // if(leftMatch != null) {
+ // leftCopy.remove(leftMatch);
+ // result.add(leftMatch);
+ // }
+ // }
+ // // Finally, set the value of our attribute to this new list
+ // leftElement.eSet(attribute, result);
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link AttributeOrderChangeMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final AttributeOrderChange theDiff = (AttributeOrderChange)this.diff;
+ // final EAttribute attribute = theDiff.getAttribute();
+ // final EObject leftElement = theDiff.getLeftElement();
+ // final EObject rightElement = theDiff.getRightElement();
+ //
+ // final List<Object> leftList = (List<Object>)leftElement.eGet(attribute);
+ // final List<Object> rightList = (List<Object>)rightElement.eGet(attribute);
+ //
+ // /*
+ // * We need to transform the "right" list into the "left" list, modulo missing values. In practical
+ // * terms, this means that we'll simply leave untouched any element that has no match in the "left"
+ // * list (elements that were added) while reordering the others in the order they have in the "left"
+ // * list.
+ // */
+ // final List<Object> rightCopy = new ArrayList<Object>(rightList);
+ // final List<Object> result = new ArrayList<Object>(rightList.size());
+ // // Add all unmatched values in the result list
+ // for(int i = 0; i < rightList.size(); i++) {
+ // final Object right = rightList.get(i);
+ //
+ // boolean hasMatch = false;
+ // for(int j = 0; !hasMatch && j < leftList.size(); j++) {
+ // hasMatch = !areDistinctValues(right, leftList.get(j));
+ // }
+ //
+ // if(!hasMatch) {
+ // rightCopy.remove(right);
+ // result.add(right);
+ // }
+ // }
+ // // Then reorder according to the left list's order
+ // for(int i = 0; i < leftList.size(); i++) {
+ // final Object left = leftList.get(i);
+ //
+ // Object rightMatch = null;
+ // for(int j = 0; rightMatch == null && j < rightCopy.size(); j++) {
+ // if(!areDistinctValues(left, rightCopy.get(j))) {
+ // rightMatch = rightCopy.get(j);
+ // }
+ // }
+ //
+ // if(rightMatch != null) {
+ // rightCopy.remove(rightMatch);
+ // result.add(rightMatch);
+ // }
+ // }
+ // // Finally, set the value of our attribute to this new list
+ // rightElement.eSet(attribute, result);
+ // }
+
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ final AttributeOrderChange theDiff = (AttributeOrderChange)this.diff;
+ final EAttribute attribute = theDiff.getAttribute();
+ final EObject leftElement = theDiff.getLeftElement();
+ final EObject rightElement = theDiff.getRightElement();
+
+ final List<Object> leftList = (List<Object>)leftElement.eGet(attribute);
+ final List<Object> rightList = (List<Object>)rightElement.eGet(attribute);
+
+ /*
+ * We need to transform the "left" list into the "right" list, modulo missing values. In practical
+ * terms, this means that we'll simply leave untouched any element that has no match in the "right"
+ * list (elements that were deleted) while reordering the others in the order they have in the "right"
+ * list.
+ */
+ final List<Object> leftCopy = new ArrayList<Object>(leftList);
+ final List<Object> result = new ArrayList<Object>(leftList.size());
+ // Add all unmatched values in the result list
+ for(int i = 0; i < leftList.size(); i++) {
+ final Object left = leftList.get(i);
+
+ boolean hasMatch = false;
+ for(int j = 0; !hasMatch && j < rightList.size(); j++) {
+ hasMatch = !areDistinctValues(left, rightList.get(j));
+ }
+
+ if(!hasMatch) {
+ leftCopy.remove(left);
+ result.add(left);
+ }
+ }
+ // Then reorder according to the right list's order
+ for(int i = 0; i < rightList.size(); i++) {
+ final Object right = rightList.get(i);
+
+ Object leftMatch = null;
+ for(int j = 0; leftMatch == null && j < leftCopy.size(); j++) {
+ if(!areDistinctValues(right, leftCopy.get(j))) {
+ leftMatch = leftCopy.get(j);
+ }
+ }
+
+ if(leftMatch != null) {
+ leftCopy.remove(leftMatch);
+ result.add(leftMatch);
+ }
+ }
+ // Finally, set the value of our attribute to this new list
+ // leftElement.eSet(attribute, result);
+ return PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, leftElement, attribute, result);
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ final AttributeOrderChange theDiff = (AttributeOrderChange)this.diff;
+ final EAttribute attribute = theDiff.getAttribute();
+ final EObject leftElement = theDiff.getLeftElement();
+ final EObject rightElement = theDiff.getRightElement();
+
+ final List<Object> leftList = (List<Object>)leftElement.eGet(attribute);
+ final List<Object> rightList = (List<Object>)rightElement.eGet(attribute);
+
+ /*
+ * We need to transform the "right" list into the "left" list, modulo missing values. In practical
+ * terms, this means that we'll simply leave untouched any element that has no match in the "left"
+ * list (elements that were added) while reordering the others in the order they have in the "left"
+ * list.
+ */
+ final List<Object> rightCopy = new ArrayList<Object>(rightList);
+ final List<Object> result = new ArrayList<Object>(rightList.size());
+ // Add all unmatched values in the result list
+ for(int i = 0; i < rightList.size(); i++) {
+ final Object right = rightList.get(i);
+
+ boolean hasMatch = false;
+ for(int j = 0; !hasMatch && j < leftList.size(); j++) {
+ hasMatch = !areDistinctValues(right, leftList.get(j));
+ }
+
+ if(!hasMatch) {
+ rightCopy.remove(right);
+ result.add(right);
+ }
+ }
+ // Then reorder according to the left list's order
+ for(int i = 0; i < leftList.size(); i++) {
+ final Object left = leftList.get(i);
+
+ Object rightMatch = null;
+ for(int j = 0; rightMatch == null && j < rightCopy.size(); j++) {
+ if(!areDistinctValues(left, rightCopy.get(j))) {
+ rightMatch = rightCopy.get(j);
+ }
+ }
+
+ if(rightMatch != null) {
+ rightCopy.remove(rightMatch);
+ result.add(rightMatch);
+ }
+ }
+ // Finally, set the value of our attribute to this new list
+ // rightElement.eSet(attribute, result);
+ return PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, rightElement, attribute, result);
+ }
+
+
+ /**
+ * This method uses the reflexive way to call the static method of the super class
+ *
+ * @param left
+ * the left object
+ * @param right
+ * the right object
+ * @return
+ * <code>true</code> if the 2 objects are dictinct.
+ */
+ //TODO write a JUnit test to be sure that this methods is always accessible
+ protected boolean areDistinctValues(final Object left, final Object right) {
+
+ final Class<?>[] parameterTypes = new Class[2];
+ parameterTypes[0] = java.lang.Object.class;
+ parameterTypes[1] = java.lang.Object.class;
+ Method m = null;
+ try {
+ m = ReflectHelper.getMethod(AttributeOrderChangeMerger.class, "areDistinctValues", parameterTypes); //$NON-NLS-1$
+ } catch (SecurityException e) {
+ Activator.log.error(e);
+ } catch (NoSuchMethodException e) {
+ Activator.log.error(e);
+ }
+
+ Object[] parameters = new Object[2];
+ parameters[0] = left;
+ parameters[1] = right;
+
+ Object result = null;
+ try {
+ result = m.invoke(AttributeOrderChangeMerger.class, parameters);
+ } catch (IllegalArgumentException e) {
+ Activator.log.error(e);
+ } catch (IllegalAccessException e) {
+ Activator.log.error(e);
+ } catch (InvocationTargetException e) {
+ Activator.log.error(e);
+ }
+ assert (result instanceof Boolean);
+ return ((Boolean)result).booleanValue();
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultExtensionTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultExtensionTransactionalMerger.java
new file mode 100644
index 00000000000..5cc9046a09d
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultExtensionTransactionalMerger.java
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ * Adapted code from EMF-Compare
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.IdentityCommand;
+import org.eclipse.emf.compare.diff.metamodel.AbstractDiffExtension;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+
+
+public class DefaultExtensionTransactionalMerger extends DefaultTransactionalMerger {
+
+ public Command getDoApplyInOriginCommand(TransactionalEditingDomain domain) {
+ return IdentityCommand.INSTANCE;
+ }
+
+ public Command getDoUndoInTargetCommand(TransactionalEditingDomain domain) {
+ return IdentityCommand.INSTANCE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#getDependencies(boolean)
+ */
+ @Override
+ protected List<DiffElement> getDependencies(boolean applyInOrigin) {
+ final List<DiffElement> requiredDiffs = diff.getRequires();
+ return getBusinessDependencies(applyInOrigin, requiredDiffs);
+ }
+
+ /**
+ * Get the difference dependencies to consider in the context of the merge process.
+ *
+ * @param applyInOrigin
+ * Direction of merge.
+ * @param requiredDiffs
+ * The required differences.
+ * @return The required differences to keep.
+ */
+ protected List<DiffElement> getBusinessDependencies(boolean applyInOrigin, List<DiffElement> requiredDiffs) {
+ final List<DiffElement> result = new ArrayList<DiffElement>();
+ for (DiffElement diffElement : requiredDiffs) {
+ if (!(diffElement instanceof AbstractDiffExtension)
+ || diffElement instanceof AbstractDiffExtension
+ && isBusinessDependency(applyInOrigin, (AbstractDiffExtension)diffElement)) {
+ result.add(diffElement);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Check if the given required difference extension has to be considered in relation to the direction of
+ * merge.
+ *
+ * @param applyInOrigin
+ * Direction of merge.
+ * @param requiredDiff
+ * The required difference.
+ * @return True if it has to be considered in the merge.
+ */
+ protected boolean isBusinessDependency(boolean applyInOrigin, final AbstractDiffExtension requiredDiff) {
+ return true;
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultTransactionalMerger.java
new file mode 100644
index 00000000000..52eaf63e37b
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DefaultTransactionalMerger.java
@@ -0,0 +1,724 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.command.IdentityCommand;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.diff.merge.EMFCompareEObjectCopier;
+import org.eclipse.emf.compare.diff.merge.IMergeListener;
+import org.eclipse.emf.compare.diff.merge.IMerger;
+import org.eclipse.emf.compare.diff.merge.MergeEvent;
+import org.eclipse.emf.compare.diff.merge.service.MergeFactory;
+import org.eclipse.emf.compare.diff.merge.service.MergeService;
+import org.eclipse.emf.compare.diff.metamodel.ConflictingDiffElement;
+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.metamodel.ModelElementChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChange;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.UpdateReference;
+import org.eclipse.emf.compare.util.ClassUtils;
+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.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.CopyWithReferenceCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.merge.ITransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.service.TransactionalMergeFactory;
+import org.eclipse.papyrus.infra.emf.compare.diff.service.TransactionalMergeService;
+import org.eclipse.papyrus.infra.emf.compare.diff.utils.PapyrusCompareOptionsUtils;
+import org.eclipse.papyrus.infra.emf.compare.diff.utils.PapyrusOptionsAdapter;
+
+/**
+ *
+ * should replace DefaultMerger
+ *
+ */
+//TODO can we remove IMerger?
+public class DefaultTransactionalMerger extends AbstractDefaultMerger implements ITransactionalMerger {
+
+ //---------------------These methods comes from ITransactionalMerger
+ public Command getApplyInOriginCommand(TransactionalEditingDomain domain, Collection<DiffElement> alreadyManaged) {
+ final PapyrusOptionsAdapter adapter = PapyrusCompareOptionsUtils.getPapyrusOptionsAdapter(diff);
+ //cf bug 396267: [UML Compare] it is not possible to merge a difference on a stereotype property
+ //final CompoundCommand cmd = new CompoundCommand(NLS.bind("Apply in Origin Command for {0}", this.diff)); //$NON-NLS-1$
+ final CompoundCommand cmd = new CompoundCommand(NLS.bind("Apply in Origin Command for {0}", this.diff.getClass())); //$NON-NLS-1$
+ if(adapter==null || adapter.canApplyInOrigin()) {
+ cmd.append(getMergeRequiredDifferencesCommand(domain, true, alreadyManaged));
+ cmd.append(getDoApplyInOriginCommand(domain));
+ cmd.append(getPostProcessCommand(domain));
+ } else {
+ cmd.append(UnexecutableCommand.INSTANCE);
+ }
+ return cmd;
+ }
+
+ public Command getUndoInTargetCommand(TransactionalEditingDomain domain, Collection<DiffElement> alreadyManaged) {
+ final PapyrusOptionsAdapter adapter = PapyrusCompareOptionsUtils.getPapyrusOptionsAdapter(diff);
+ //cf bug 396267: [UML Compare] it is not possible to merge a difference on a stereotype property
+ //final CompoundCommand cmd = new CompoundCommand(NLS.bind("Undo in Target Command for {0}", this.diff)); //$NON-NLS-1$
+ final CompoundCommand cmd = new CompoundCommand(NLS.bind("Undo in Target Command for {0}", this.diff.getClass())); //$NON-NLS-1$
+ if(adapter == null || adapter.canUndoInTarget()) {
+ cmd.append(getMergeRequiredDifferencesCommand(domain, false, alreadyManaged));
+ cmd.append(getDoUndoInTargetCommand(domain));
+ cmd.append(getPostProcessCommand(domain));
+ } else {
+ cmd.append(UnexecutableCommand.INSTANCE);
+ }
+ return cmd;
+ }
+
+ public Command getDoApplyInOriginCommand(TransactionalEditingDomain domain) {
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ public Command getDoUndoInTargetCommand(TransactionalEditingDomain domain) {
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ public Command getMergeRequiredDifferencesCommand(TransactionalEditingDomain domain, boolean applyInOrigin, Collection<DiffElement> alreadyManaged) {
+ CompoundCommand cmd = new CompoundCommand("Merge required differences"); //$NON-NLS-1$
+ // if(mergedDiffs == null) { //we need to clean it, to avoid that the command creation duplicate elements in this list
+ mergedDiffs = new ArrayList<DiffElement>();
+ if(mergedDiffslistener == null) {
+ //TODO : improve that, and use command!
+ mergedDiffslistener = new MergedDiffsListener();
+ TransactionalMergeService.addMergeListener(mergedDiffslistener);
+ }
+ // }
+ mergedDiffs.add(diff);
+
+ for(DiffElement requiredDiff : getDependencies(applyInOrigin)) {
+ if(requiredDiff.eContainer() != null && !alreadyManaged.contains(requiredDiff)) {
+ final ITransactionalMerger merger = TransactionalMergeFactory.createMerger(requiredDiff);
+ alreadyManaged.add(requiredDiff);
+ if(applyInOrigin) {
+ cmd.append(((ITransactionalMerger)merger).getApplyInOriginCommand(domain, alreadyManaged));
+ } else {
+ cmd.append(((ITransactionalMerger)merger).getUndoInTargetCommand(domain, alreadyManaged));
+ }
+ }
+ }
+ if(cmd.isEmpty()) {
+ return IdentityCommand.INSTANCE;
+ }
+ return cmd;
+ }
+
+ public Command getPostProcessCommand(TransactionalEditingDomain domain) {
+ return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Merge Required Differences", null) { //$NON-NLS-1$
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ handleMutuallyDerivedReferences();
+ //ensureXMIIDCopied();
+ if(getDiffModel() != null) {//383515: [UML Compare] NPE with ReferenceChangeRightTarget leftToRight and ReferenceChangeLeftTarget rightToLeft
+ final EMFCompareEObjectCopier copier = TransactionalMergeService.getCopier(diff);
+ copier.copyXMIIDs();
+ }
+ removeFromContainer(diff);
+ return null;
+ }
+ });
+ }
+
+ //TODO move it in an upper class
+ protected static TransactionalEditingDomain getTransactionalEditingDomain(final DiffElement diff) {
+ DiffElement diffElement = diff;
+ final Iterator<EObject> iter = diff.eAllContents();
+ while(iter.hasNext()) {
+ final EObject current = iter.next();
+ if(current instanceof DiffElement && !(current instanceof DiffGroup)) {
+ diffElement = (DiffElement)current;
+ break;
+ }
+ }
+ //we try to get the EditingDomain using the left object AND the rightObject,
+ //because in some case it should be interesting to do a comparison between an object contained by a resource
+ //and an other object no contained by a resource
+ EObject element = (EObject)ClassUtils.invokeMethod(diffElement, "getRightElement"); //$NON-NLS-1$
+ if(element == null) {
+ element = (EObject)ClassUtils.invokeMethod(diffElement, "getLeftElement"); //$NON-NLS-1$
+ }
+ TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(element);
+
+ if(domain == null) {
+ element = (EObject)ClassUtils.invokeMethod(diffElement, "getRightParent"); //$NON-NLS-1$
+ if(element == null) {
+ element = (EObject)ClassUtils.invokeMethod(diffElement, "getLeftParent"); //$NON-NLS-1$
+ }
+ domain = TransactionUtil.getEditingDomain(element);
+ }
+ assert domain!=null; //cf bug 396267: [UML Compare] it is not possible to merge a difference on a stereotype property
+// Assert.isNotNull(domain, NLS.bind("I didn't found the EditingDomain for {0}", diff)); //$NON-NLS-1$
+ return domain;
+
+ }
+
+ public boolean canApplyInOrigin() {
+ return getApplyInOriginCommand(getTransactionalEditingDomain(diff), new ArrayList<DiffElement>()).canExecute();
+ }
+
+
+ public boolean canUndoInTarget() {
+ return getUndoInTargetCommand(getTransactionalEditingDomain(diff), new ArrayList<DiffElement>()).canExecute();
+ }
+
+ //---------------------from Here to the end : duplicated and adapted code from DefaultMerger
+ /** The scheme used for all of EMF Compare's internal proxies. */
+ private static final String PROXY_SCHEME = "emfCompareProxy"; //$NON-NLS-1$
+
+ /** Stores the differences which are merged or being merged during a merge operation. */
+ private static List<DiffElement> mergedDiffs;
+
+ /** This listener will be used to reset the {@link mergedDiffs} list at the end of a merge operation. */
+ private static MergedDiffsListener mergedDiffslistener;
+
+ /** {@link DiffElement} to be merged by this merger. */
+ protected DiffElement diff;
+
+ /** Keeps a reference on the left resource for this merger. */
+ @Deprecated
+ protected Resource leftResource;
+
+ /** Keeps a reference on the right resource for this merger. */
+ @Deprecated
+ protected Resource rightResource;
+
+ /**
+ * Reset the {@link mergedDiffs} list.
+ *
+ * @since 1.3
+ */
+ protected static void resetMergedDiffs() {
+ mergedDiffs = null;
+ }
+
+ /**
+ * Returns <code>true</code> if the given URI is an internal EMF Compare proxy.
+ *
+ * @param uri
+ * The URI to check.
+ * @return <code>true</code> if the given URI is an internal EMF Compare proxy.
+ * @since 1.3
+ */
+ public static boolean isEMFCompareProxy(URI uri) {
+ return uri.scheme() != null && uri.scheme().equals(PROXY_SCHEME);
+ }
+
+ /**
+ * Checks whether the two given proxy URIs are equal, ignoring EMF Compare's internal {@link #PROXY_PREFIX}.
+ *
+ * @param uri1
+ * First of the two URIs to compare.
+ * @param uri2
+ * Second of the two URIs to compare.
+ * @return <code>true</code> if the two given URIs are equal.
+ *
+ * @since 1.3
+ */
+ public static boolean equalProxyURIs(URI uri1, URI uri2) {
+ String stringValue1 = uri1.toString();
+ String stringValue2 = uri2.toString();
+ if(isEMFCompareProxy(uri1)) {
+ stringValue1 = stringValue1.substring(PROXY_SCHEME.length() + 2);
+ }
+ if(isEMFCompareProxy(uri2)) {
+ stringValue2 = stringValue2.substring(PROXY_SCHEME.length() + 2);
+ }
+ return stringValue1.equals(stringValue2);
+ }
+
+ // /**
+ // * {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.IMerger#applyInOrigin()
+ // */
+ // public void applyInOrigin() {
+ // mergeRequiredDifferences(true);
+ // doApplyInOrigin();
+ // postProcess();
+ // }
+ //
+ // /**
+ // * Applies the modification in the original (left) model.
+ // *
+ // * @since 1.3
+ // */
+ // protected void doApplyInOrigin() {
+ // // To specialize in child class.
+ // }
+ //
+ // /**
+ // * Applies a post processing.
+ // *
+ // * @since 1.3
+ // */
+ // protected void postProcess() {
+ // handleMutuallyDerivedReferences();
+ // ensureXMIIDCopied();
+ // removeFromContainer(diff);
+ // }
+
+ // /**
+ // * {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.IMerger#canApplyInOrigin()
+ // */
+ // public boolean canApplyInOrigin() {
+ // return true;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.IMerger#canUndoInTarget()
+ // */
+ // public boolean canUndoInTarget() {
+ // return true;
+ // }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.IMerger#setDiffElement(org.eclipse.emf.compare.diff.metamodel.DiffElement)
+ */
+ public void setDiffElement(DiffElement element) {
+ diff = element;
+ }
+
+ // /**
+ // * {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.IMerger#undoInTarget()
+ // */
+ // public void undoInTarget() {
+ // mergeRequiredDifferences(false);
+ // doUndoInTarget();
+ // postProcess();
+ // }
+ //
+ // /**
+ // * Cancels the modification in the target (right) model.
+ // *
+ // * @since 1.3
+ // */
+ // protected void doUndoInTarget() {
+ // // To specialize in child class.
+ // }
+
+ /**
+ * Removes the given {@link DiffGroup} from its container if it was its last child, also calls for the
+ * same cleanup operation on its hierarchy.
+ *
+ * @param diffGroup
+ * {@link DiffGroup} we want to cleanup.
+ */
+ protected void cleanDiffGroup(DiffGroup diffGroup) {
+ if(diffGroup != null && diffGroup.getSubDiffElements().size() == 0) {
+ final EObject parent = diffGroup.eContainer();
+ if(parent instanceof DiffGroup) {
+ EcoreUtil.remove(diffGroup);
+ cleanDiffGroup((DiffGroup)parent);
+ }
+ }
+ }
+
+ // /**
+ // * Creates a copy of the given EObject as would {@link EcoreUtil#copy(EObject)} would, except we use
+ // * specific handling for unmatched references.
+ // *
+ // * @param eObject
+ // * The object to copy.
+ // * @return the copied object.
+ // */
+ // protected EObject copy(EObject eObject) {
+ // final EMFCompareEObjectCopier copier = TransactionalMergeService.getCopier(diff);
+ // if(copier.containsKey(eObject)) {
+ // //385289: [UML Compare] Bad result after merginf UMLStereotypeApplicationAddition/Removal
+ // //in some case, the elements are copied and merged twice!
+ // return copier.get(eObject);
+ // }
+ // final EObject result = copier.copy(eObject);
+ // copier.copyReferences();
+ // copier.copyXMIIDs();
+ // return result;
+ // }
+
+ /**
+ *
+ * @param eObject
+ * the eobject copy
+ * @return
+ * the result of the command is the copiedObject
+ * the copied object is immediately available doing copyCommand.getCommandResult().getReturnValue();
+ */
+ protected AbstractTransactionalCommand getCopyWithReferenceCommand(final EObject eObject) {
+ return new CopyWithReferenceCommand(getTransactionalEditingDomain(diff), TransactionalMergeService.getCopier(diff), eObject);
+ }
+
+ /**
+ * This can be called after a merge operation to ensure that all objects created by the operation share
+ * the same XMI ID as their original.
+ * <p>
+ * Implemented because of bug 351591 : some of the objects we copy mays not have been added to a resource when we check their IDs. We thus need to
+ * wait till the merge operation has completed.
+ * </p>
+ *
+ * @since 1.3
+ */
+ protected void ensureXMIIDCopied() {
+ final EMFCompareEObjectCopier copier = TransactionalMergeService.getCopier(diff);
+ copier.copyXMIIDs();
+ }
+
+ /**
+ * Returns the {@link DiffModel} containing the {@link DiffElement} this merger is intended to merge.
+ *
+ * @return The {@link DiffModel} containing the {@link DiffElement} this merger is intended to merge.
+ */
+ protected DiffModel getDiffModel() {
+ EObject container = diff.eContainer();
+ while(container != null) {
+ if(container instanceof DiffModel)
+ return (DiffModel)container;
+ container = container.eContainer();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the XMI ID of the given {@link EObject} or <code>null</code> if it cannot be resolved.
+ *
+ * @param object
+ * Object which we seek the XMI ID of.
+ * @return <code>object</code>'s XMI ID, <code>null</code> if not applicable.
+ */
+ protected String getXMIID(EObject object) {
+ String objectID = null;
+ if(object != null && object.eResource() instanceof XMIResource) {
+ objectID = ((XMIResource)object.eResource()).getID(object);
+ }
+ return objectID;
+ }
+
+ /**
+ * Removes all references to the given {@link EObject} from the {@link DiffModel}.
+ *
+ * @param deletedObject
+ * 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());
+ // }
+ // }
+ // }
+ }
+
+ /**
+ * Removes a {@link DiffElement} from its {@link DiffGroup}.
+ *
+ * @param diffElement
+ * {@link DiffElement} to remove from its container.
+ */
+ protected void removeFromContainer(DiffElement diffElement) {
+ final EObject parent = diffElement.eContainer();
+ EcoreUtil.remove(diffElement);
+ removeDanglingReferences(parent);
+
+ // If diff was contained by a ConflictingDiffElement, we call back this on it
+ if(parent instanceof ConflictingDiffElement) {
+ removeFromContainer((DiffElement)parent);
+ }
+
+ // if diff was in a diffGroup and it was the last one, we also remove the diffgroup
+ if(parent instanceof DiffGroup) {
+ cleanDiffGroup((DiffGroup)parent);
+ }
+ }
+
+ /**
+ * Sets the XMI ID of the given {@link EObject} if it belongs in an {@link XMIResource}.
+ *
+ * @param object
+ * Object we want to set the XMI ID of.
+ * @param id
+ * XMI ID to give to <code>object</code>.
+ */
+ protected void setXMIID(EObject object, String id) {
+ if(object != null && object.eResource() instanceof XMIResource) {
+ ((XMIResource)object.eResource()).setID(object, id);
+ }
+ }
+
+ /**
+ * Merge the differences required by the current difference.
+ *
+ * @param applyInOrigin
+ * True if the merge has to apply in origin.
+ * @since 1.3
+ */
+ protected void mergeRequiredDifferences(boolean applyInOrigin) {
+ if(mergedDiffs == null) {
+ mergedDiffs = new ArrayList<DiffElement>();
+ if(mergedDiffslistener == null) {
+ mergedDiffslistener = new MergedDiffsListener();
+ MergeService.addMergeListener(mergedDiffslistener);
+ }
+ }
+ mergedDiffs.add(diff);
+
+ for(DiffElement requiredDiff : getDependencies(applyInOrigin)) {
+ if(requiredDiff.eContainer() != null && !mergedDiffs.contains(requiredDiff)) {
+ final IMerger merger = MergeFactory.createMerger(requiredDiff);
+ if(applyInOrigin) {
+ merger.applyInOrigin();
+ } else {
+ merger.undoInTarget();
+ }
+ }
+ }
+ }
+
+ /**
+ * This default merge listener will allow us to reset the {@link #mergedDiffs} list at the end of the
+ * merge operation.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ */
+ private class MergedDiffsListener implements IMergeListener {
+
+ /**
+ * Default constructor.
+ */
+ public MergedDiffsListener() {
+ // Enhance visibility of the default constructor.
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.IMergeListener#mergeDiffEnd(org.eclipse.emf.compare.diff.merge.MergeEvent)
+ */
+ public void mergeDiffEnd(MergeEvent event) {
+ // do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.IMergeListener#mergeDiffStart(org.eclipse.emf.compare.diff.merge.MergeEvent)
+ */
+ public void mergeDiffStart(MergeEvent event) {
+ // do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.IMergeListener#mergeOperationEnd(org.eclipse.emf.compare.diff.merge.MergeEvent)
+ */
+ public void mergeOperationEnd(MergeEvent event) {
+ resetMergedDiffs();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.IMergeListener#mergeOperationStart(org.eclipse.emf.compare.diff.merge.MergeEvent)
+ */
+ public void mergeOperationStart(MergeEvent event) {
+ // do nothing
+ }
+ }
+
+ /**
+ * Get the dependencies of the difference {@link diff} to merge. These dependencies will be merged before
+ * itself. This method may be overridden by a specific merger to choose to exploit or not the 'requires'
+ * link of the {@link diff} according to the nature of the merger and the direction of the merge.
+ *
+ * @param applyInOrigin
+ * The direction of the merge.
+ * @return The list of the dependencies to exploit.
+ * @since 1.3
+ */
+ protected List<DiffElement> getDependencies(boolean applyInOrigin) {
+ return new ArrayList<DiffElement>();
+ }
+
+ /**
+ * Mutually derived references need specific handling : merging one will implicitely merge the other and
+ * there are no way to tell such references apart.
+ * <p>
+ * Currently known references raising such issues :
+ * <table>
+ * <tr>
+ * <td>{@link EcorePackage#ECLASS__ESUPER_TYPES}</td>
+ * <td>{@link EcorePackage#ECLASS__EGENERIC_SUPER_TYPES}</td>
+ * </tr>
+ * </table>
+ * </p>
+ */
+ private void handleMutuallyDerivedReferences() {
+ DiffElement toRemove = null;
+ if(diff instanceof ReferenceChange) {
+ final EReference reference = ((ReferenceChange)diff).getReference();
+ if(reference == EcorePackage.eINSTANCE.getEClass_ESuperTypes()) {
+ EObject referenceType = null;
+ if(diff instanceof ReferenceChangeLeftTarget) {
+ referenceType = ((ReferenceChangeLeftTarget)diff).getRightTarget();
+ } else if(diff instanceof ReferenceChangeRightTarget) {
+ referenceType = ((ReferenceChangeRightTarget)diff).getLeftTarget();
+ } else if(diff instanceof UpdateReference) {
+ referenceType = ((UpdateReference)diff).getLeftTarget();
+ } else {
+ // we did cover all the subclasses, we should have a RferenceOrderChange
+ }
+ for(final DiffElement siblingDiff : ((DiffGroup)diff.eContainer()).getSubDiffElements()) {
+ if(siblingDiff instanceof ModelElementChangeLeftTarget) {
+ if(((ModelElementChangeLeftTarget)siblingDiff).getLeftElement() instanceof EGenericType && ((EGenericType)((ModelElementChangeLeftTarget)siblingDiff).getLeftElement()).getEClassifier() == referenceType) {
+ toRemove = siblingDiff;
+ break;
+ }
+ } else if(siblingDiff instanceof ModelElementChangeRightTarget) {
+ if(((ModelElementChangeRightTarget)siblingDiff).getRightElement() instanceof EGenericType && ((EGenericType)((ModelElementChangeRightTarget)siblingDiff).getRightElement()).getEClassifier() == referenceType) {
+ toRemove = siblingDiff;
+ break;
+ }
+ }
+ }
+ }
+ } else if(diff instanceof ModelElementChangeLeftTarget && ((ModelElementChangeLeftTarget)diff).getLeftElement() instanceof EGenericType) {
+ final ModelElementChangeLeftTarget theDiff = (ModelElementChangeLeftTarget)diff;
+ final EClassifier referenceType = ((EGenericType)theDiff.getLeftElement()).getEClassifier();
+ for(final DiffElement siblingDiff : ((DiffGroup)diff.eContainer()).getSubDiffElements()) {
+ if(siblingDiff instanceof ReferenceChangeLeftTarget && ((ReferenceChangeLeftTarget)siblingDiff).getReference().getFeatureID() == EcorePackage.ECLASS__ESUPER_TYPES) {
+ if(((ReferenceChangeLeftTarget)siblingDiff).getRightTarget() == referenceType) {
+ toRemove = siblingDiff;
+ break;
+ }
+ }
+ }
+ } else if(diff instanceof ModelElementChangeRightTarget && ((ModelElementChangeRightTarget)diff).getRightElement() instanceof EGenericType) {
+ final ModelElementChangeRightTarget theDiff = (ModelElementChangeRightTarget)diff;
+ final EClassifier referenceType = ((EGenericType)theDiff.getRightElement()).getEClassifier();
+ for(final DiffElement siblingDiff : ((DiffGroup)diff.eContainer()).getSubDiffElements()) {
+ if(siblingDiff instanceof ReferenceChangeRightTarget && ((ReferenceChangeRightTarget)siblingDiff).getReference().getFeatureID() == EcorePackage.ECLASS__ESUPER_TYPES) {
+ if(((ReferenceChangeRightTarget)siblingDiff).getLeftTarget() == referenceType) {
+ toRemove = siblingDiff;
+ break;
+ }
+ }
+ }
+ }
+ if(toRemove != null) {
+ removeFromContainer(toRemove);
+ }
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DiffGroupTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DiffGroupTransactionalMerger.java
new file mode 100644
index 00000000000..5aa5b3e36c7
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/DiffGroupTransactionalMerger.java
@@ -0,0 +1,106 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.diff.metamodel.DiffGroup;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.service.TransactionalMergeService;
+
+/**
+ *
+ * Transactional version of the class DiffGroupMerger provided by EMF Compare
+ *
+ */
+public class DiffGroupTransactionalMerger extends DefaultTransactionalMerger {
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.DefaultTransactionalMerger#getApplyInOriginCommand(org.eclipse.emf.transaction.TransactionalEditingDomain, Collection)
+ *
+ * @param domain
+ * @return
+ */
+ public Command getApplyInOriginCommand(final TransactionalEditingDomain domain, Collection<DiffElement> alreadyManaged) {
+ if(somethingToMerge((DiffGroup)diff)) {
+ return TransactionalMergeService.getMergeCommand(domain, diff.getSubDiffElements(), false);
+ }
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.DefaultTransactionalMerger#getUndoInTargetCommand(org.eclipse.emf.transaction.TransactionalEditingDomain, Collection)
+ *
+ * @param domain
+ * @return
+ */
+ public Command getUndoInTargetCommand(final TransactionalEditingDomain domain, Collection<DiffElement> alreadyManaged) {
+ if(somethingToMerge((DiffGroup)diff)) {
+ return TransactionalMergeService.getMergeCommand(domain, diff.getSubDiffElements(), true); // doUndoInTarget();
+ }
+ return UnexecutableCommand.INSTANCE;
+ }
+
+ /**
+ *
+ * @param group
+ * @return
+ * <code>true</code> if we found DiffElement that is not a DiffGroup in the content of the DiffElement
+ */
+ protected boolean somethingToMerge(final DiffGroup group) {
+ final Iterator<EObject> iter = group.eAllContents();
+ while(iter.hasNext()) {
+ final EObject current = iter.next();
+ if(current instanceof DiffElement && !(current instanceof DiffGroup)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.DefaultTransactionalMerger#canApplyInOrigin()
+ *
+ * @return
+ */
+ @Override
+ public boolean canApplyInOrigin() {
+ if(somethingToMerge(((DiffGroup)diff))) {
+ return super.canApplyInOrigin();
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.DefaultTransactionalMerger#canUndoInTarget()
+ *
+ * @return
+ */
+ @Override
+ public boolean canUndoInTarget() {
+ if(somethingToMerge(((DiffGroup)diff))) {
+ return super.canUndoInTarget();
+ }
+ return false;
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeLeftTargetTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeLeftTargetTransactionalMerger.java
new file mode 100644
index 00000000000..35efe3e008f
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeLeftTargetTransactionalMerger.java
@@ -0,0 +1,229 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.diff.metamodel.DiffModel;
+import org.eclipse.emf.compare.diff.metamodel.ModelElementChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceOrderChange;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.commands.AddToResourceCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.CopyXMIIDCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.PapyrusMergeCommandProvider;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+
+
+/**
+ *
+ * Transactional version of the class {@link ModelElementChangeLeftTargetMerger}
+ *
+ */
+public class ModelElementChangeLeftTargetTransactionalMerger extends DefaultTransactionalMerger {//ModelElementChangeLeftTargetMerger implements ITransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link ModelElementChangeLeftTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // protected void doApplyInOrigin() {
+ // final ModelElementChangeLeftTarget theDiff = (ModelElementChangeLeftTarget)this.diff;
+ // final EObject element = theDiff.getLeftElement();
+ // final EObject parent = theDiff.getLeftElement().eContainer();
+ // EcoreUtil.remove(element);
+ // // now removes all the dangling references
+ // removeDanglingReferences(parent);
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link ModelElementChangeLeftTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // */
+ // @Override
+ // protected void doUndoInTarget() {
+ // final ModelElementChangeLeftTarget theDiff = (ModelElementChangeLeftTarget)this.diff;
+ // // we should copy the element to the Origin one.
+ // final EObject origin = theDiff.getRightParent();
+ // final EObject element = theDiff.getLeftElement();
+ // final EObject newOne = copy(element);
+ // final EReference ref = element.eContainmentFeature();
+ // if(ref != null) {
+ // try {
+ // int elementIndex = -1;
+ // if(ref.isMany()) {
+ // final Object containmentRefVal = element.eContainer().eGet(ref);
+ // if(containmentRefVal instanceof List<?>) {
+ // @SuppressWarnings("unchecked")
+ // final List<EObject> listVal = (List<EObject>)containmentRefVal;
+ // elementIndex = listVal.indexOf(element);
+ // }
+ // }
+ // EFactory.eAdd(origin, ref.getName(), newOne, elementIndex, true);
+ // setXMIID(newOne, getXMIID(element));
+ // } catch (final FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // } else if(origin == null && getDiffModel().getRightRoots().size() > 0) {
+ // getDiffModel().getRightRoots().get(0).eResource().getContents().add(newOne);
+ // } else if(origin != null) {
+ // origin.eResource().getContents().add(newOne);
+ // } else {
+ // // FIXME throw exception : couldn't merge this
+ // }
+ // // we should now have a look for RemovedReferencesLinks needing elements to apply
+ // final Iterator<EObject> siblings = getDiffModel().eAllContents();
+ // while(siblings.hasNext()) {
+ // final Object op = siblings.next();
+ // if(op instanceof ReferenceChangeLeftTarget) {
+ // final ReferenceChangeLeftTarget link = (ReferenceChangeLeftTarget)op;
+ // // now if I'm in the target References I should put my copy in the origin
+ // if(link.getRightTarget() != null && link.getRightTarget() == element) {
+ // link.setLeftTarget(newOne);
+ // }
+ // } else if(op instanceof ReferenceOrderChange) {
+ // final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ // if(link.getRightElement() == origin && link.getReference() == ref) {
+ // final ListIterator<EObject> targetIterator = link.getRightTarget().listIterator();
+ // boolean replaced = false;
+ // while(!replaced && targetIterator.hasNext()) {
+ // final EObject target = targetIterator.next();
+ // if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(element))) {
+ // targetIterator.set(newOne);
+ // replaced = true;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // }
+
+ //TODO verify that I use this method in the transactional version
+ /**
+ * The native implementation, duplicated Code from {@link ModelElementChangeLeftTargetMerger} {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#getDependencies(boolean)
+ */
+ @Override
+ protected List<DiffElement> getDependencies(boolean applyInOrigin) {
+ if(!applyInOrigin) {
+ return diff.getRequires();
+ }
+ return super.getDependencies(applyInOrigin);
+ }
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ final ModelElementChangeLeftTarget theDiff = (ModelElementChangeLeftTarget)this.diff;
+ final EObject element = theDiff.getLeftElement();
+ return PapyrusMergeCommandProvider.INSTANCE.getDestroyCommand(domain, element);
+ //removeDanglingReferences(parent); not used
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ CompoundCommand cmd = new CompoundCommand("Command CModelElementChangeLeftTargetMerger#getDoUndoInTargetCommand"); //$NON-NLS-1$
+ final ModelElementChangeLeftTarget theDiff = (ModelElementChangeLeftTarget)this.diff;
+ // we should copy the element to the Origin one.
+ final EObject origin = theDiff.getRightParent();
+ final EObject element = theDiff.getLeftElement();
+ final ICommand copyCommand = getCopyWithReferenceCommand(element);
+ cmd.append(new GMFtoEMFCommandWrapper(copyCommand));
+ final EObject newOne = (EObject)copyCommand.getCommandResult().getReturnValue();
+ final EReference ref = element.eContainmentFeature();
+ if(ref != null) {
+ try {
+ int elementIndex = -1;
+ if(ref.isMany()) {
+ final Object containmentRefVal = element.eContainer().eGet(ref);
+ if(containmentRefVal instanceof List<?>) {
+ @SuppressWarnings("unchecked")
+ final List<EObject> listVal = (List<EObject>)containmentRefVal;
+ elementIndex = listVal.indexOf(element);
+ }
+ }
+ // EFactory.eAdd(origin, ref.getName(), newOne, elementIndex, true);
+ // setXMIID(newOne, getXMIID(element));
+ cmd.append(PapyrusEFactory.getEAddCommand(domain, origin, ref.getName(), newOne, elementIndex, true));
+ cmd.append(new CopyXMIIDCommand(element, newOne));
+ } catch (final FactoryException e) {
+ Activator.log.error(e);
+ }
+ } else if(origin == null && getDiffModel().getRightRoots().size() > 0) {
+ // getDiffModel().getRightRoots().get(0).eResource().getContents().add(newOne);
+ cmd.append(new AddToResourceCommand(getDiffModel().getRightRoots().get(0).eResource(), newOne));
+ } else if(origin != null) {
+ // origin.eResource().getContents().add(newOne);
+ cmd.append(new AddToResourceCommand(origin.eResource(), newOne));
+ } else {
+ // FIXME throw exception : couldn't merge this
+ }
+ cmd.append(new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "", null) { //$NON-NLS-1$
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // we should now have a look for RemovedReferencesLinks needing elements to apply
+ final DiffModel diffModel = getDiffModel();//see bug 385263: [UML Compare] NPE merging a DiffGroup owning a UMLStereotypeApplicationAddition/Removal
+ if(diffModel != null) {
+ final Iterator<EObject> siblings = diffModel.eAllContents();
+ while(siblings.hasNext()) {
+ final Object op = siblings.next();
+ if(op instanceof ReferenceChangeLeftTarget) {
+ final ReferenceChangeLeftTarget link = (ReferenceChangeLeftTarget)op;
+ // now if I'm in the target References I should put my copy in the origin
+ if(link.getRightTarget() != null && link.getRightTarget() == element) {
+ link.setLeftTarget(newOne);
+ }
+ } else if(op instanceof ReferenceOrderChange) {
+ final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ if(link.getRightElement() == origin && link.getReference() == ref) {
+ final ListIterator<EObject> targetIterator = link.getRightTarget().listIterator();
+ boolean replaced = false;
+ while(!replaced && targetIterator.hasNext()) {
+ final EObject target = targetIterator.next();
+ if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(element))) {
+ targetIterator.set(newOne);
+ replaced = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ }));
+
+ return cmd;
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeRightTargetTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeRightTargetTransactionalMerger.java
new file mode 100644
index 00000000000..28ecd6891ac
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ModelElementChangeRightTargetTransactionalMerger.java
@@ -0,0 +1,235 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.diff.metamodel.DiffModel;
+import org.eclipse.emf.compare.diff.metamodel.ModelElementChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceOrderChange;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.commands.AddToResourceCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.CopyXMIIDCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.PapyrusMergeCommandProvider;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+
+/**
+ *
+ * Transactional version of the class {@link ModelElementChangeRightTargetMerger}
+ *
+ */
+
+public class ModelElementChangeRightTargetTransactionalMerger extends DefaultTransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link ModelElementChangeRightTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final ModelElementChangeRightTarget theDiff = (ModelElementChangeRightTarget)this.diff;
+ // final EObject origin = theDiff.getLeftParent();
+ // final EObject element = theDiff.getRightElement();
+ // final EObject newOne = copy(element);
+ // final EReference ref = element.eContainmentFeature();
+ // if(ref != null) {
+ // try {
+ // int expectedIndex = -1;
+ // if(ref.isMany()) {
+ // final Object containmentRefVal = element.eContainer().eGet(ref);
+ // if(containmentRefVal instanceof List<?>) {
+ // @SuppressWarnings("unchecked")
+ // final List<EObject> listVal = (List<EObject>)containmentRefVal;
+ // expectedIndex = listVal.indexOf(element);
+ // }
+ // }
+ // EFactory.eAdd(origin, ref.getName(), newOne, expectedIndex, true);
+ // setXMIID(newOne, getXMIID(element));
+ // } catch (final FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // } else if(origin == null && getDiffModel().getLeftRoots().size() > 0) {
+ // getDiffModel().getLeftRoots().get(0).eResource().getContents().add(newOne);
+ // } else if(origin != null) {
+ // origin.eResource().getContents().add(newOne);
+ // } else {
+ // // FIXME Throw exception : couldn't merge this
+ // }
+ // // we should now have a look for AddReferencesLinks needing this object
+ // final Iterator<EObject> siblings = getDiffModel().eAllContents();
+ // while(siblings.hasNext()) {
+ // final DiffElement op = (DiffElement)siblings.next();
+ // if(op instanceof ReferenceChangeRightTarget) {
+ // final ReferenceChangeRightTarget link = (ReferenceChangeRightTarget)op;
+ // // now if I'm in the target References I should put my copy in the origin
+ // if(link.getLeftTarget() != null && link.getLeftTarget() == element) {
+ // link.setRightTarget(newOne);
+ // }
+ // } else if(op instanceof ReferenceOrderChange) {
+ // final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ // if(link.getLeftElement() == origin && link.getReference() == ref) {
+ // final ListIterator<EObject> targetIterator = link.getLeftTarget().listIterator();
+ // boolean replaced = false;
+ // while(!replaced && targetIterator.hasNext()) {
+ // final EObject target = targetIterator.next();
+ // if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(element))) {
+ // targetIterator.set(newOne);
+ // replaced = true;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link ModelElementChangeRightTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final ModelElementChangeRightTarget theDiff = (ModelElementChangeRightTarget)this.diff;
+ // final EObject element = theDiff.getRightElement();
+ // final EObject parent = theDiff.getRightElement().eContainer();
+ // EcoreUtil.remove(element);
+ // // now removes all the dangling references
+ // removeDanglingReferences(parent);
+ // }
+
+ /**
+ * The native implementation, duplicated Code from {@link ModelElementChangeRightTargetMerger} {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#canUndoInTarget()
+ */
+ @Override
+ public boolean canUndoInTarget() {
+ final ModelElementChangeRightTarget theDiff = (ModelElementChangeRightTarget)this.diff;
+ final boolean isRightElementNotNull = theDiff.getRightElement() != null;
+ return isRightElementNotNull;
+ }
+
+ //TODO verify if I use this method
+ /**
+ * The native implementation, duplicated Code from {@link ModelElementChangeRightTargetMerger} {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#getDependencies(boolean)
+ */
+ @Override
+ protected List<DiffElement> getDependencies(boolean applyInOrigin) {
+ if(applyInOrigin) {
+ return diff.getRequires();
+ }
+ return super.getDependencies(applyInOrigin);
+ }
+
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ final CompoundCommand cmd = new CompoundCommand("Command CModelElementChangeRightTargetMerger#getDoApplyInOriginCommand"); //$NON-NLS-1$
+ final ModelElementChangeRightTarget theDiff = (ModelElementChangeRightTarget)this.diff;
+ final EObject origin = theDiff.getLeftParent();
+ final EObject element = theDiff.getRightElement();
+ final ICommand copyCommand = getCopyWithReferenceCommand(element);
+ cmd.append(new GMFtoEMFCommandWrapper(copyCommand));
+ final EObject newOne = (EObject)copyCommand.getCommandResult().getReturnValue();
+ final EReference ref = element.eContainmentFeature();
+ if(ref != null) {
+ try {
+ int expectedIndex = -1;
+ if(ref.isMany()) {
+ final Object containmentRefVal = element.eContainer().eGet(ref);
+ if(containmentRefVal instanceof List<?>) {
+ @SuppressWarnings("unchecked")
+ final List<EObject> listVal = (List<EObject>)containmentRefVal;
+ expectedIndex = listVal.indexOf(element);
+ }
+ }
+ // EFactory.eAdd(origin, ref.getName(), newOne, expectedIndex, true);
+ // setXMIID(newOne, getXMIID(element));
+ cmd.append(PapyrusEFactory.getEAddCommand(domain, origin, ref.getName(), newOne, expectedIndex, true));
+ cmd.append(new CopyXMIIDCommand(element, newOne));
+ } catch (final FactoryException e) {
+ Activator.log.error(e);
+ }
+ } else if(origin == null && getDiffModel().getLeftRoots().size() > 0) {
+ cmd.append(new AddToResourceCommand(getDiffModel().getLeftRoots().get(0).eResource(), newOne));
+ } else if(origin != null) {
+ cmd.append(new AddToResourceCommand(origin.eResource(), newOne));
+ } else {
+ // FIXME Throw exception : couldn't merge this
+ }
+ cmd.append(new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, null, null) {
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // we should now have a look for AddReferencesLinks needing this object
+ final DiffModel diffModel = getDiffModel();////see bug 385263: [UML Compare] NPE merging a DiffGroup owning a UMLStereotypeApplicationAddition/Removal
+ if(diffModel != null) {
+ final Iterator<EObject> siblings = diffModel.eAllContents();
+ while(siblings.hasNext()) {
+ final DiffElement op = (DiffElement)siblings.next();
+ if(op instanceof ReferenceChangeRightTarget) {
+ final ReferenceChangeRightTarget link = (ReferenceChangeRightTarget)op;
+ // now if I'm in the target References I should put my copy in the origin
+ if(link.getLeftTarget() != null && link.getLeftTarget() == element) {
+ link.setRightTarget(newOne);
+ }
+ } else if(op instanceof ReferenceOrderChange) {
+ final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ if(link.getLeftElement() == origin && link.getReference() == ref) {
+ final ListIterator<EObject> targetIterator = link.getLeftTarget().listIterator();
+ boolean replaced = false;
+ while(!replaced && targetIterator.hasNext()) {
+ final EObject target = targetIterator.next();
+ if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(element))) {
+ targetIterator.set(newOne);
+ replaced = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ }));
+ return cmd;
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ final ModelElementChangeRightTarget theDiff = (ModelElementChangeRightTarget)this.diff;
+ final EObject element = theDiff.getRightElement();
+ return PapyrusMergeCommandProvider.INSTANCE.getDestroyCommand(domain, element);
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/MoveModelElementTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/MoveModelElementTransactionalMerger.java
new file mode 100644
index 00000000000..2d40055f550
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/MoveModelElementTransactionalMerger.java
@@ -0,0 +1,226 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.compare.diff.metamodel.MoveModelElement;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.PapyrusMergeCommandProvider;
+
+/**
+ *
+ * Transactional version of the class {@link MoveModelElementMerger}
+ *
+ */
+public class MoveModelElementTransactionalMerger extends DefaultTransactionalMerger {//MoveModelElementMerger implements ITransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link MoveModelElementMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // */
+ // @SuppressWarnings("unchecked")
+ // @Override
+ // public void doApplyInOrigin() {
+ // final MoveModelElement theDiff = (MoveModelElement)this.diff;
+ // final EObject leftTarget = theDiff.getLeftTarget();
+ // final EObject leftElement = theDiff.getLeftElement();
+ // final EReference ref = theDiff.getRightElement().eContainmentFeature();
+ // if(ref != null) {
+ // // ordering handling:
+ // int index = -1;
+ // final EObject rightElementParent = theDiff.getRightElement().eContainer();
+ // final Object rightRefValue = rightElementParent.eGet(ref);
+ // if(rightRefValue instanceof List) {
+ // final List<Object> refRightValueList = (List<Object>)rightRefValue;
+ // index = refRightValueList.indexOf(theDiff.getRightElement());
+ // }
+ //
+ // try {
+ // // We'll store the element's ID because moving an element deletes its XMI ID
+ // final String elementID = getXMIID(leftElement);
+ // EcoreUtil.remove(leftElement);
+ // EFactory.eAdd(leftTarget, ref.getName(), leftElement, index, true);
+ // // Sets anew the element's ID
+ // setXMIID(leftElement, elementID);
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // } else {
+ // // shouldn't be here
+ // assert false;
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link MoveModelElementMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // */
+ // @SuppressWarnings("unchecked")
+ // @Override
+ // public void doUndoInTarget() {
+ // final MoveModelElement theDiff = (MoveModelElement)this.diff;
+ // final EObject rightTarget = theDiff.getRightTarget();
+ // final EObject rightElement = theDiff.getRightElement();
+ // final EReference ref = theDiff.getLeftElement().eContainmentFeature();
+ // if(ref != null) {
+ // // ordering handling:
+ // int index = -1;
+ // final EObject leftElementParent = theDiff.getLeftElement().eContainer();
+ // final Object leftRefValue = leftElementParent.eGet(ref);
+ // if(leftRefValue instanceof List) {
+ // final List<Object> refLeftValueList = (List<Object>)leftRefValue;
+ // index = refLeftValueList.indexOf(theDiff.getLeftElement());
+ // }
+ //
+ // try {
+ // final String elementID = getXMIID(rightElement);
+ // EcoreUtil.remove(rightElement);
+ // EFactory.eAdd(rightTarget, ref.getName(), rightElement, index, true);
+ // setXMIID(rightElement, elementID);
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // } else {
+ // // shouldn't be here
+ // assert false;
+ // }
+ // }
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ final CompoundCommand cmd = new CompoundCommand("CMoveModelElementMerger#getDoApplyInOriginCommand"); //$NON-NLS-1$
+ final MoveModelElement theDiff = (MoveModelElement)this.diff;
+ final EObject leftTarget = theDiff.getLeftTarget();
+ final EObject leftElement = theDiff.getLeftElement();
+ final EReference ref = theDiff.getRightElement().eContainmentFeature();
+ if(ref != null) {
+ // ordering handling:
+ int index = -1;
+ final EObject rightElementParent = theDiff.getRightElement().eContainer();
+ final Object rightRefValue = rightElementParent.eGet(ref);
+ if(rightRefValue instanceof List) {
+ final List<Object> refRightValueList = (List<Object>)rightRefValue;
+ index = refRightValueList.indexOf(theDiff.getRightElement());
+ }
+
+
+ // We'll store the element's ID because moving an element deletes its XMI ID
+ final String elementID = getXMIID(leftElement);
+
+ if(rightRefValue instanceof List<?>) {
+ cmd.append(PapyrusMergeCommandProvider.INSTANCE.getMoveWithIndexCommand(domain, leftTarget, leftTarget, ref, leftElement, index, true));
+ } else {
+ cmd.append(PapyrusMergeCommandProvider.INSTANCE.getMoveCommand(domain, leftTarget, leftTarget, ref, leftElement));
+ }
+ cmd.append(getPreserveXMIIDCommand(domain, leftElement, elementID));
+
+ } else {
+ // shouldn't be here
+ cmd.append(UnexecutableCommand.INSTANCE);
+ }
+ return cmd;
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ final CompoundCommand cmd = new CompoundCommand("CMoveModelElementMerger#getDoUndoInTargetCommand"); //$NON-NLS-1$
+ final MoveModelElement theDiff = (MoveModelElement)this.diff;
+ final EObject rightTarget = theDiff.getRightTarget();
+ final EObject rightElement = theDiff.getRightElement();
+ final EReference ref = theDiff.getLeftElement().eContainmentFeature();
+ if(ref != null) {
+ // ordering handling:
+ int index = -1;
+ final EObject leftElementParent = theDiff.getLeftElement().eContainer();
+ final Object leftRefValue = leftElementParent.eGet(ref);
+ if(leftRefValue instanceof List) {
+ final List<Object> refLeftValueList = (List<Object>)leftRefValue;
+ index = refLeftValueList.indexOf(theDiff.getLeftElement());
+ }
+ if(leftRefValue instanceof List<?>) {
+ cmd.append(PapyrusMergeCommandProvider.INSTANCE.getMoveWithIndexCommand(domain, rightTarget, rightTarget, ref, rightElement, index, true));
+ } else {
+ cmd.append(PapyrusMergeCommandProvider.INSTANCE.getMoveCommand(domain, rightTarget, rightTarget, ref, rightElement));
+ }
+ final String elementID = getXMIID(rightElement);
+ cmd.append(getPreserveXMIIDCommand(domain, rightElement, elementID));
+ } else {
+ // shouldn't be here
+ cmd.append(UnexecutableCommand.INSTANCE);
+ }
+ return cmd;
+ }
+
+
+ // public Command getMergeRequiredDifferencesCommand(final TransactionalEditingDomain domain, final boolean applyInOrigin) {
+ // // TODO the super method mergeRequiredDifferences should be rewritten to use cmd too
+ // return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Merge Required Differences", null) { //$NON-NLS-1$
+ //
+ // @Override
+ // protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // MoveModelElementTransactionalMerger.this.mergeRequiredDifferences(applyInOrigin);
+ // return null;
+ // }
+ // });
+ // }
+ //
+ // public Command getPostProcessCommand(final TransactionalEditingDomain domain) {
+ // return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Merge Required Differences", null) { //$NON-NLS-1$
+ //
+ // @Override
+ // protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // MoveModelElementTransactionalMerger.this.postProcess();
+ // return null;
+ // }
+ // });
+ // }
+
+ /**
+ * This command is not the the class PapyrusUMLMergeProvider because it only should be used to preserve the xmi_id after a move,
+ * but not to change the id
+ *
+ * @param domain
+ * @param element
+ * @param id
+ * @return
+ * the command to set the ID
+ */
+ private Command getPreserveXMIIDCommand(final TransactionalEditingDomain domain, final EObject element, final String id) {
+ //TODO change for an EMFCommand
+ return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Set XMI Command", null) { //$NON-NLS-1$
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ if(element != null && element.eResource() instanceof XMIResource) {
+ ((XMIResource)element.eResource()).setID(element, id);
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ });
+
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeLeftTargetTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeLeftTargetTransactionalMerger.java
new file mode 100644
index 00000000000..c5c6b27e414
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeLeftTargetTransactionalMerger.java
@@ -0,0 +1,274 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.diff.metamodel.DiffModel;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceOrderChange;
+import org.eclipse.emf.compare.diff.metamodel.ResourceDependencyChange;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusCompareEObjectCopier;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+import org.eclipse.papyrus.infra.emf.compare.diff.service.TransactionalMergeService;
+
+/**
+ *
+ * Transactional version of the class {@link ReferenceChangeLeftTargetMerger}
+ *
+ */
+public class ReferenceChangeLeftTargetTransactionalMerger extends DefaultTransactionalMerger {//ReferenceChangeLeftTargetMerger implements ITransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link ReferenceChangeLeftTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final ReferenceChangeLeftTarget theDiff = (ReferenceChangeLeftTarget)this.diff;
+ // final EObject element = theDiff.getLeftElement();
+ // final EObject leftTarget = theDiff.getLeftTarget();
+ // try {
+ // EFactory.eRemove(element, theDiff.getReference().getName(), leftTarget);
+ // } catch (final FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // // we should now have a look for AddReferencesLinks needing this object
+ // final Iterator<EObject> siblings = getDiffModel().eAllContents();
+ // while(siblings.hasNext()) {
+ // final DiffElement op = (DiffElement)siblings.next();
+ // if(op instanceof ReferenceChangeLeftTarget) {
+ // final ReferenceChangeLeftTarget link = (ReferenceChangeLeftTarget)op;
+ // // now if I'm in the target References I should put my copy in the origin
+ // if(link.getReference().equals(theDiff.getReference().getEOpposite()) && link.getLeftTarget().equals(element)) {
+ // removeFromContainer(link);
+ // }
+ // } else if(op instanceof ResourceDependencyChange) {
+ // final ResourceDependencyChange link = (ResourceDependencyChange)op;
+ // final Resource res = link.getRoots().get(0).eResource();
+ // if(res == leftTarget.eResource()) {
+ // EcoreUtil.remove(link);
+ // res.unload();
+ // }
+ // }
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link ReferenceChangeLeftTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final ReferenceChangeLeftTarget theDiff = (ReferenceChangeLeftTarget)this.diff;
+ // final EReference reference = theDiff.getReference();
+ // final EObject element = theDiff.getRightElement();
+ // final EObject leftTarget = theDiff.getLeftTarget();
+ // final EObject rightTarget = theDiff.getRightTarget();
+ //
+ // int index = -1;
+ // if(reference.isMany()) {
+ // final EObject leftElement = theDiff.getLeftElement();
+ // final Object leftRefValue = leftElement.eGet(reference);
+ // if(leftRefValue instanceof List) {
+ // final List refLeftValueList = (List)leftRefValue;
+ // index = refLeftValueList.indexOf(leftTarget);
+ // }
+ // }
+ // final EObject copiedValue = MergeService.getCopier(diff).copyReferenceValue(reference, element, leftTarget, rightTarget, index);
+ //
+ // // we should now have a look for AddReferencesLinks needing this object
+ // final Iterator<EObject> siblings = getDiffModel().eAllContents();
+ // while(siblings.hasNext()) {
+ // final DiffElement op = (DiffElement)siblings.next();
+ // if(op instanceof ReferenceChangeLeftTarget) {
+ // final ReferenceChangeLeftTarget link = (ReferenceChangeLeftTarget)op;
+ // // now if I'm in the target References I should put my copy in the origin
+ // if(link.getReference().equals(reference.getEOpposite()) && link.getLeftTarget().equals(element)) {
+ // removeFromContainer(link);
+ // }
+ // } else if(op instanceof ReferenceOrderChange) {
+ // final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ // if(link.getLeftElement() == element && link.getReference() == reference) {
+ // final ListIterator<EObject> targetIterator = link.getLeftTarget().listIterator();
+ // boolean replaced = false;
+ // while(!replaced && targetIterator.hasNext()) {
+ // final EObject target = targetIterator.next();
+ // if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(leftTarget))) {
+ // targetIterator.set(copiedValue);
+ // replaced = true;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // }
+
+ //TODO : verify if I use this method
+ /**
+ * The native implementation, duplicated Code from {@link ReferenceChangeLeftTargetMerger} {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#getDependencies(boolean)
+ */
+ @Override
+ protected List<DiffElement> getDependencies(boolean applyInOrigin) {
+ if(!applyInOrigin) {
+ return diff.getRequires();
+ }
+ return super.getDependencies(applyInOrigin);
+ }
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ final CompoundCommand cmd = new CompoundCommand("CReferenceChangeLeftTargetMerger#getDoApplyInOriginCommand"); //$NON-NLS-1$
+ final ReferenceChangeLeftTarget theDiff = (ReferenceChangeLeftTarget)this.diff;
+ final EObject element = theDiff.getLeftElement();
+ final EObject leftTarget = theDiff.getLeftTarget();
+ try {
+ cmd.append(PapyrusEFactory.getERemoveCommand(domain, element, theDiff.getReference().getName(), leftTarget));
+ } catch (final FactoryException e) {
+ Activator.log.error(e);
+ }
+ cmd.append(new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, null, null) {
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ final DiffModel diffModel = getDiffModel();
+ if(diffModel != null) {//383515: [UML Compare] NPE with ReferenceChangeRightTarget leftToRight and ReferenceChangeLeftTarget rightToLeft
+ // we should now have a look for AddReferencesLinks needing this object
+ final Iterator<EObject> siblings = diffModel.eAllContents();
+ while(siblings.hasNext()) {
+ final DiffElement op = (DiffElement)siblings.next();
+ if(op instanceof ReferenceChangeLeftTarget) {
+ final ReferenceChangeLeftTarget link = (ReferenceChangeLeftTarget)op;
+ // now if I'm in the target References I should put my copy in the origin
+ if(link.getReference().equals(theDiff.getReference().getEOpposite()) && link.getLeftTarget().equals(element)) {
+ removeFromContainer(link);
+ }
+ } else if(op instanceof ResourceDependencyChange) {
+ final ResourceDependencyChange link = (ResourceDependencyChange)op;
+ final Resource res = link.getRoots().get(0).eResource();
+ if(res == leftTarget.eResource()) {
+ EcoreUtil.remove(link);
+ res.unload();
+ }
+ }
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ }));
+ return cmd;
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ final CompoundCommand cmd = new CompoundCommand();
+ final ReferenceChangeLeftTarget theDiff = (ReferenceChangeLeftTarget)this.diff;
+ final EReference reference = theDiff.getReference();
+ final EObject element = theDiff.getRightElement();
+ final EObject leftTarget = theDiff.getLeftTarget();
+ final EObject rightTarget = theDiff.getRightTarget();
+
+ int index = -1;
+ if(reference.isMany()) {
+ final EObject leftElement = theDiff.getLeftElement();
+ final Object leftRefValue = leftElement.eGet(reference);
+ if(leftRefValue instanceof List) {
+ final List<?> refLeftValueList = (List<?>)leftRefValue;
+ index = refLeftValueList.indexOf(leftTarget);
+ }
+ }
+ final PapyrusCompareEObjectCopier copier = (PapyrusCompareEObjectCopier)TransactionalMergeService.getCopier(diff);
+ Command copierCommand = copier.getCopyReferenceValueCommand(domain, reference, element, leftTarget, rightTarget, index);
+ cmd.append(copierCommand);
+ final AbstractTransactionalCommand updateDiffModelCommand = new AbstractTransactionalCommand(domain, "Update Diff Model", null) { //$NON-NLS-1$
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ final EObject copiedValue = copier.getCopiedValue(leftTarget);
+ final Iterator<EObject> siblings = getDiffModel().eAllContents();
+ while(siblings.hasNext()) {
+ final DiffElement op = (DiffElement)siblings.next();
+ if(op instanceof ReferenceChangeLeftTarget) {
+ final ReferenceChangeLeftTarget link = (ReferenceChangeLeftTarget)op;
+ // now if I'm in the target References I should put my copy in the origin
+ if(link.getReference().equals(reference.getEOpposite()) && link.getLeftTarget().equals(element)) {
+ removeFromContainer(link);
+ }
+ } else if(op instanceof ReferenceOrderChange) {
+ final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ if(link.getLeftElement() == element && link.getReference() == reference) {
+ final ListIterator<EObject> targetIterator = link.getLeftTarget().listIterator();
+ boolean replaced = false;
+ while(!replaced && targetIterator.hasNext()) {
+ final EObject target = targetIterator.next();
+ if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(leftTarget))) {
+ targetIterator.set(copiedValue);
+ replaced = true;
+ }
+ }
+ }
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ };
+ cmd.append(new GMFtoEMFCommandWrapper(updateDiffModelCommand));
+ return cmd;
+ }
+
+ // public Command getMergeRequiredDifferencesCommand(final TransactionalEditingDomain domain, final boolean applyInOrigin) {
+ // return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Merge Required Differences", null) { //$NON-NLS-1$
+ //
+ // @Override
+ // protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // ReferenceChangeLeftTargetTransactionalMerger.this.mergeRequiredDifferences(applyInOrigin);
+ // return null;
+ // }
+ // });
+ // }
+ //
+ // public Command getPostProcessCommand(final TransactionalEditingDomain domain) {
+ // return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Merge Required Differences", null) { //$NON-NLS-1$
+ //
+ // @Override
+ // protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // ReferenceChangeLeftTargetTransactionalMerger.this.postProcess();
+ // return null;
+ // }
+ // });
+ // }
+
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeRightTargetTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeRightTargetTransactionalMerger.java
new file mode 100644
index 00000000000..e50c2c80806
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceChangeRightTargetTransactionalMerger.java
@@ -0,0 +1,277 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.diff.metamodel.DiffModel;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceOrderChange;
+import org.eclipse.emf.compare.diff.metamodel.ResourceDependencyChange;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusCompareEObjectCopier;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+import org.eclipse.papyrus.infra.emf.compare.diff.service.TransactionalMergeService;
+
+/**
+ *
+ * Transactional version of the class {@link ReferenceChangeRightTargetMerger}
+ *
+ */
+public class ReferenceChangeRightTargetTransactionalMerger extends DefaultTransactionalMerger {//ReferenceChangeRightTargetMerger implements ITransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link ReferenceChangeRightTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final ReferenceChangeRightTarget theDiff = (ReferenceChangeRightTarget)this.diff;
+ // final EReference reference = theDiff.getReference();
+ // final EObject element = theDiff.getLeftElement();
+ // final EObject rightTarget = theDiff.getRightTarget();
+ // final EObject leftTarget = theDiff.getLeftTarget();
+ //
+ // // ordering handling:
+ // int index = -1;
+ // if(reference.isMany()) {
+ // final EObject rightElement = theDiff.getRightElement();
+ // final Object rightRefValue = rightElement.eGet(reference);
+ // if(rightRefValue instanceof List) {
+ // final List refRightValueList = (List)rightRefValue;
+ // index = refRightValueList.indexOf(rightTarget);
+ // }
+ // }
+ // final EObject copiedValue = MergeService.getCopier(diff).copyReferenceValue(reference, element, rightTarget, leftTarget, index);
+ //
+ // // We'll now look through this reference's eOpposite as they are already taken care of
+ // final Iterator<EObject> related = getDiffModel().eAllContents();
+ // while(related.hasNext()) {
+ // final DiffElement op = (DiffElement)related.next();
+ // if(op instanceof ReferenceChangeRightTarget) {
+ // final ReferenceChangeRightTarget link = (ReferenceChangeRightTarget)op;
+ // // If this is my eOpposite, delete it from the DiffModel (merged along with this one)
+ // if(link.getReference().equals(theDiff.getReference().getEOpposite()) && link.getRightTarget().equals(element)) {
+ // removeFromContainer(link);
+ // }
+ // } else if(op instanceof ReferenceOrderChange) {
+ // final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ // if(link.getLeftElement() == element && link.getReference() == reference) {
+ // final ListIterator<EObject> targetIterator = link.getLeftTarget().listIterator();
+ // boolean replaced = false;
+ // while(!replaced && targetIterator.hasNext()) {
+ // final EObject target = targetIterator.next();
+ // if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(rightTarget))) {
+ // targetIterator.set(copiedValue);
+ // replaced = true;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link ReferenceChangeRightTargetMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final ReferenceChangeRightTarget theDiff = (ReferenceChangeRightTarget)this.diff;
+ // final EObject element = theDiff.getRightElement();
+ // final EObject rightTarget = theDiff.getRightTarget();
+ // try {
+ // EFactory.eRemove(element, theDiff.getReference().getName(), rightTarget);
+ // } catch (final FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // // we should now have a look for AddReferencesLinks needing this object
+ // final Iterator<EObject> related = getDiffModel().eAllContents();
+ // while(related.hasNext()) {
+ // final DiffElement op = (DiffElement)related.next();
+ // if(op instanceof ReferenceChangeRightTarget) {
+ // final ReferenceChangeRightTarget link = (ReferenceChangeRightTarget)op;
+ // // now if I'm in the target References I should put my copy in the origin
+ // if(link.getReference().equals(theDiff.getReference().getEOpposite()) && link.getRightTarget().equals(element)) {
+ // removeFromContainer(link);
+ // }
+ // } else if(op instanceof ResourceDependencyChange) {
+ // final ResourceDependencyChange link = (ResourceDependencyChange)op;
+ // final Resource res = link.getRoots().get(0).eResource();
+ // if(res == rightTarget.eResource()) {
+ // EcoreUtil.remove(link);
+ // res.unload();
+ // }
+ // }
+ // }
+ // }
+
+ //TODO : verify that I use this method
+ /**
+ * The native implementation, duplicated Code from {@link ReferenceChangeRightTargetMerger} {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#getDependencies(boolean)
+ */
+ @Override
+ protected List<DiffElement> getDependencies(boolean applyInOrigin) {
+ if(applyInOrigin) {
+ return diff.getRequires();
+ }
+ return super.getDependencies(applyInOrigin);
+ }
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ CompoundCommand cmd = new CompoundCommand("Undo In Target Command for CReferenceChangeRightTargetMerger#getDoApplyInOriginCommand"); //$NON-NLS-1$
+ final ReferenceChangeRightTarget theDiff = (ReferenceChangeRightTarget)this.diff;
+ final EReference reference = theDiff.getReference();
+ final EObject element = theDiff.getLeftElement();
+ final EObject rightTarget = theDiff.getRightTarget();
+ final EObject leftTarget = theDiff.getLeftTarget();
+
+ // ordering handling:
+ int index = -1;
+ if(reference.isMany()) {
+ final EObject rightElement = theDiff.getRightElement();
+ final Object rightRefValue = rightElement.eGet(reference);
+ if(rightRefValue instanceof List) {
+ final List<?> refRightValueList = (List<?>)rightRefValue;
+ index = refRightValueList.indexOf(rightTarget);
+ }
+ }
+ final PapyrusCompareEObjectCopier copier = (PapyrusCompareEObjectCopier)TransactionalMergeService.getCopier(diff);
+ cmd.append(copier.getCopyReferenceValueCommand(domain, reference, element, rightTarget, leftTarget, index));
+
+ cmd.append(new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "", null) { //$NON-NLS-1$
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ final EObject copiedValue = copier.getCopiedValue(rightTarget);
+ // We'll now look through this reference's eOpposite as they are already taken care of
+ final Iterator<EObject> related = getDiffModel().eAllContents();
+ while(related.hasNext()) {
+ final DiffElement op = (DiffElement)related.next();
+ if(op instanceof ReferenceChangeRightTarget) {
+ final ReferenceChangeRightTarget link = (ReferenceChangeRightTarget)op;
+ // If this is my eOpposite, delete it from the DiffModel (merged along with this one)
+ if(link.getReference().equals(theDiff.getReference().getEOpposite()) && link.getRightTarget().equals(element)) {
+ removeFromContainer(link);
+ }
+ } else if(op instanceof ReferenceOrderChange) {
+ final ReferenceOrderChange link = (ReferenceOrderChange)op;
+ if(link.getLeftElement() == element && link.getReference() == reference) {
+ final ListIterator<EObject> targetIterator = link.getLeftTarget().listIterator();
+ boolean replaced = false;
+ while(!replaced && targetIterator.hasNext()) {
+ final EObject target = targetIterator.next();
+ if(target.eIsProxy() && equalProxyURIs(((InternalEObject)target).eProxyURI(), EcoreUtil.getURI(rightTarget))) {
+ targetIterator.set(copiedValue);
+ replaced = true;
+ }
+ }
+ }
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ }));
+
+ return cmd;
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ CompoundCommand cmd = new CompoundCommand("Undo In Target Command for CReferenceChangeRightTargetMerger#getDoUndoInTargetCommand"); //$NON-NLS-1$
+ final ReferenceChangeRightTarget theDiff = (ReferenceChangeRightTarget)this.diff;
+ final EObject element = theDiff.getRightElement();
+ final EObject rightTarget = theDiff.getRightTarget();
+ try {
+ cmd.append(PapyrusEFactory.getERemoveCommand(domain, element, theDiff.getReference().getName(), rightTarget));
+ } catch (final FactoryException e) {
+ Activator.log.error(e);
+ }
+ cmd.append(new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, null, null) {
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ final DiffModel diffModel = getDiffModel();
+ if(diffModel != null) {//383515: [UML Compare] NPE with ReferenceChangeRightTarget leftToRight and ReferenceChangeLeftTarget rightToLeft
+ // we should now have a look for AddReferencesLinks needing this object
+ final Iterator<EObject> related = diffModel.eAllContents();
+ while(related.hasNext()) {
+ final DiffElement op = (DiffElement)related.next();
+ if(op instanceof ReferenceChangeRightTarget) {
+ final ReferenceChangeRightTarget link = (ReferenceChangeRightTarget)op;
+ // now if I'm in the target References I should put my copy in the origin
+ if(link.getReference().equals(theDiff.getReference().getEOpposite()) && link.getRightTarget().equals(element)) {
+ removeFromContainer(link);
+ }
+ } else if(op instanceof ResourceDependencyChange) {
+ final ResourceDependencyChange link = (ResourceDependencyChange)op;
+ final Resource res = link.getRoots().get(0).eResource();
+ if(res == rightTarget.eResource()) {
+ EcoreUtil.remove(link);
+ res.unload();
+ }
+ }
+ }
+ }
+ return CommandResult.newOKCommandResult();
+ }
+ }));
+
+ return cmd;
+ }
+
+ // public Command getMergeRequiredDifferencesCommand(final TransactionalEditingDomain domain, final boolean applyInOrigin) {
+ // // TODO the super method mergeRequiredDifferences should be rewritten to use cmd too
+ // return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Merge Required Differences", null) { //$NON-NLS-1$
+ //
+ // @Override
+ // protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // ReferenceChangeRightTargetTransactionalMerger.this.mergeRequiredDifferences(applyInOrigin);
+ // return null;
+ // }
+ // });
+ // }
+ //
+ // public Command getPostProcessCommand(final TransactionalEditingDomain domain) {
+ // return new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "Merge Required Differences", null) { //$NON-NLS-1$
+ //
+ // @Override
+ // protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // ReferenceChangeRightTargetTransactionalMerger.this.postProcess();
+ // return null;
+ // }
+ // });
+ // }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceOrderChangeTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceOrderChangeTransactionalMerger.java
new file mode 100644
index 00000000000..3c849443364
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/ReferenceOrderChangeTransactionalMerger.java
@@ -0,0 +1,128 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.merge.DefaultMerger;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceOrderChange;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+
+/**
+ *
+ * Transactional version of the class {@link ReferenceOrderChangeMerger}
+ *
+ */
+public class ReferenceOrderChangeTransactionalMerger extends DefaultTransactionalMerger {
+
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link ReferenceOrderChangeMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final ReferenceOrderChange theDiff = (ReferenceOrderChange)this.diff;
+ // final EObject leftElement = theDiff.getLeftElement();
+ //
+ // final Collection<EObject> target = Lists.newArrayList(Collections2.filter(theDiff.getLeftTarget(), new Predicate<EObject>() {
+ //
+ // public boolean apply(EObject input) {
+ // return !input.eIsProxy() || !DefaultMerger.isEMFCompareProxy(((InternalEObject)input).eProxyURI());
+ // }
+ // }));
+ //
+ // try {
+ // EFactory.eSet(leftElement, theDiff.getReference().getName(), target);
+ // } catch (final FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link ReferenceOrderChangeMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final ReferenceOrderChange theDiff = (ReferenceOrderChange)this.diff;
+ // final EObject rightElement = theDiff.getRightElement();
+ //
+ // final Collection<EObject> target = Lists.newArrayList(Collections2.filter(theDiff.getRightTarget(), new Predicate<EObject>() {
+ //
+ // public boolean apply(EObject input) {
+ // return !input.eIsProxy() || !DefaultMerger.isEMFCompareProxy(((InternalEObject)input).eProxyURI());
+ // }
+ // }));
+ //
+ // try {
+ // EFactory.eSet(rightElement, theDiff.getReference().getName(), target);
+ // } catch (final FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final ReferenceOrderChange theDiff = (ReferenceOrderChange)this.diff;
+ final EObject leftElement = theDiff.getLeftElement();
+
+ final Collection<EObject> target = Lists.newArrayList(Collections2.filter(theDiff.getLeftTarget(), new Predicate<EObject>() {
+
+ public boolean apply(final EObject input) {
+ return !input.eIsProxy() || !DefaultMerger.isEMFCompareProxy(((InternalEObject)input).eProxyURI());
+ }
+ }));
+
+ try {
+ cmd = PapyrusEFactory.getESetCommand(domain, leftElement, theDiff.getReference().getName(), target);
+ } catch (final FactoryException e) {
+ Activator.log.error(e);
+ }
+ return cmd;
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final ReferenceOrderChange theDiff = (ReferenceOrderChange)this.diff;
+ final EObject rightElement = theDiff.getRightElement();
+
+ final Collection<EObject> target = Lists.newArrayList(Collections2.filter(theDiff.getRightTarget(), new Predicate<EObject>() {
+
+ public boolean apply(final EObject input) {
+ return !input.eIsProxy() || !DefaultMerger.isEMFCompareProxy(((InternalEObject)input).eProxyURI());
+ }
+ }));
+
+ try {
+ cmd = PapyrusEFactory.getESetCommand(domain, rightElement, theDiff.getReference().getName(), target);
+ } catch (final FactoryException e) {
+ Activator.log.error(e);
+ }
+ return cmd;
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateAttributeTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateAttributeTransactionalMerger.java
new file mode 100644
index 00000000000..d623cf73d40
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateAttributeTransactionalMerger.java
@@ -0,0 +1,101 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.diff.metamodel.UpdateAttribute;
+import org.eclipse.emf.compare.util.EFactory;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusEFactory;
+
+/**
+ *
+ * Transactional version of the class {@link UpdateAttributeMerger}
+ *
+ */
+public class UpdateAttributeTransactionalMerger extends DefaultTransactionalMerger {//UpdateAttributeMerger implements ITransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link UpdateAttributeMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final UpdateAttribute theDiff = (UpdateAttribute)this.diff;
+ // final EObject element = theDiff.getRightElement();
+ // final EObject origin = theDiff.getLeftElement();
+ // final EAttribute attr = theDiff.getAttribute();
+ // try {
+ // EFactory.eSet(origin, attr.getName(), EFactory.eGet(element, attr.getName()));
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link UpdateAttributeMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final UpdateAttribute theDiff = (UpdateAttribute)this.diff;
+ // final EObject element = theDiff.getRightElement();
+ // final EObject origin = theDiff.getLeftElement();
+ // final EAttribute attr = theDiff.getAttribute();
+ // try {
+ // EFactory.eSet(element, attr.getName(), EFactory.eGet(origin, attr.getName()));
+ // } catch (FactoryException e) {
+ // EMFComparePlugin.log(e, true);
+ // }
+ // }
+
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final UpdateAttribute theDiff = (UpdateAttribute)this.diff;
+ final EObject element = theDiff.getRightElement();
+ final EObject origin = theDiff.getLeftElement();
+ final EAttribute attr = theDiff.getAttribute();
+ try {
+ cmd = PapyrusEFactory.getESetCommand(domain, origin, attr.getName(), EFactory.eGet(element, attr.getName()));
+ } catch (FactoryException e) {
+ Activator.log.error(e);
+ }
+ return cmd;
+ }
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final UpdateAttribute theDiff = (UpdateAttribute)this.diff;
+ final EObject element = theDiff.getRightElement();
+ final EObject origin = theDiff.getLeftElement();
+ final EAttribute attr = theDiff.getAttribute();
+ try {
+ cmd = PapyrusEFactory.getESetCommand(domain, element, attr.getName(), EFactory.eGet(origin, attr.getName()));
+ } catch (FactoryException e) {
+ Activator.log.error(e);
+ }
+ return cmd;
+ }
+
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateReferenceTransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateReferenceTransactionalMerger.java
new file mode 100644
index 00000000000..4b211ec345a
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/merger/UpdateReferenceTransactionalMerger.java
@@ -0,0 +1,164 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.merger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.diff.metamodel.ModelElementChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.ModelElementChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.UpdateReference;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.PapyrusMergeCommandProvider;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusCompareEObjectCopier;
+import org.eclipse.papyrus.infra.emf.compare.diff.service.TransactionalMergeService;
+
+/**
+ *
+ * Transactional version of the class {@link UpdateReferenceMerger}
+ *
+ */
+public class UpdateReferenceTransactionalMerger extends DefaultTransactionalMerger {
+
+ // /**
+ // * The native implementation, duplicated Code from {@link UpdateReferenceMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doApplyInOrigin()
+ // */
+ // @Override
+ // public void doApplyInOrigin() {
+ // final UpdateReference theDiff = (UpdateReference)this.diff;
+ // final EReference reference = theDiff.getReference();
+ // final EObject element = theDiff.getLeftElement();
+ // final EObject leftTarget = (EObject)theDiff.getRightElement().eGet(reference);
+ // final EObject matchedLeftTarget = theDiff.getLeftTarget();
+ //
+ // if(leftTarget == null) {
+ // // We're unsetting the value, no need to copy
+ // element.eUnset(reference);
+ // } else {
+ // MergeService.getCopier(diff).copyReferenceValue(reference, element, leftTarget, matchedLeftTarget, -1);
+ // }
+ // }
+ //
+ // /**
+ // * The native implementation, duplicated Code from {@link UpdateReferenceMerger} {@inheritDoc}
+ // *
+ // * @see org.eclipse.emf.compare.diff.merge.api.AbstractMerger#doUndoInTarget()
+ // */
+ // @Override
+ // public void doUndoInTarget() {
+ // final UpdateReference theDiff = (UpdateReference)this.diff;
+ // final EReference reference = theDiff.getReference();
+ // final EObject element = theDiff.getRightElement();
+ // final EObject rightTarget = (EObject)theDiff.getLeftElement().eGet(reference);
+ // final EObject matchedRightTarget = theDiff.getRightTarget();
+ //
+ // if(rightTarget == null) {
+ // // We're unsetting the value, no need to copy
+ // element.eUnset(reference);
+ // } else {
+ // MergeService.getCopier(diff).copyReferenceValue(reference, element, rightTarget, matchedRightTarget, -1);
+ // }
+ // }
+
+ //TODO verify if I use this method
+ /**
+ * The native implementation, duplicated Code from {@link UpdateReferenceMerger} {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.DefaultMerger#getDependencies(boolean)
+ */
+ @Override
+ protected List<DiffElement> getDependencies(boolean applyInOrigin) {
+ final List<DiffElement> diffs = diff.getRequires();
+ final List<DiffElement> result = new ArrayList<DiffElement>();
+ for(DiffElement diffElement : diffs) {
+ if(applyInOrigin && diffElement instanceof ModelElementChangeRightTarget) {
+ result.add(diffElement);
+ } else if(!applyInOrigin && diffElement instanceof ModelElementChangeLeftTarget) {
+ result.add(diffElement);
+ }
+ }
+ return result;
+ }
+
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final UpdateReference theDiff = (UpdateReference)this.diff;
+ final EReference reference = theDiff.getReference();
+ final EObject element = theDiff.getLeftElement();
+ final EObject leftTarget = (EObject)theDiff.getRightElement().eGet(reference);
+ final EObject matchedLeftTarget = theDiff.getLeftTarget();
+
+ if(leftTarget == null) {
+ if(FeatureMapUtil.isMany(element, reference)) {
+ //TODO : I didn't find an example to test this case.
+ throw new UnsupportedOperationException("Not Yet Supported"); //$NON-NLS-1$
+ } else {
+ final Object value = theDiff.getLeftElement().eGet(reference);
+ if(value instanceof EObject) {
+ cmd = PapyrusMergeCommandProvider.INSTANCE.getDestroyReferenceCommand(domain, element, reference, (EObject)value, false);
+ } else {
+ //TODO : we don't use the ServiceEdit
+ //TODO : not tested
+ // element.eUnset(reference);
+ cmd = new SetCommand(domain, element, reference, null);
+ }
+ }
+ } else {
+ final PapyrusCompareEObjectCopier copier = (PapyrusCompareEObjectCopier)TransactionalMergeService.getCopier(diff);
+ cmd = copier.getCopyReferenceValueCommand(domain, reference, element, leftTarget, matchedLeftTarget, -1);
+ }
+ return cmd;
+ }
+
+
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain) {
+ Command cmd = null;
+ final UpdateReference theDiff = (UpdateReference)this.diff;
+ final EReference reference = theDiff.getReference();
+ final EObject element = theDiff.getRightElement();
+ final EObject rightTarget = (EObject)theDiff.getLeftElement().eGet(reference);
+ final EObject matchedRightTarget = theDiff.getRightTarget();
+
+ if(rightTarget == null) {
+ if(FeatureMapUtil.isMany(element, reference)) {
+ //TODO : I didn't find an example to test this case.
+ throw new UnsupportedOperationException("Not Yet Supported"); //$NON-NLS-1$
+ } else {
+ final Object value = theDiff.getRightElement().eGet(reference);
+ if(value instanceof EObject) {
+ cmd = PapyrusMergeCommandProvider.INSTANCE.getDestroyReferenceCommand(domain, element, reference, (EObject)value, false);
+ } else {
+ //TODO : we don't use the ServiceEdit
+ //TODO : not tested
+ // element.eUnset(reference);
+ cmd = new SetCommand(domain, element, reference, null);
+ }
+ }
+ } else {
+ final PapyrusCompareEObjectCopier copier = (PapyrusCompareEObjectCopier)TransactionalMergeService.getCopier(diff);
+ cmd = copier.getCopyReferenceValueCommand(domain, reference, element, rightTarget, matchedRightTarget, -1);
+ }
+ return cmd;
+ }
+
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/provider/DefaultTransactionalMergerProvider.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/provider/DefaultTransactionalMergerProvider.java
new file mode 100644
index 00000000000..ee95e68275b
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/provider/DefaultTransactionalMergerProvider.java
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.provider;
+
+import java.util.Map;
+
+import org.eclipse.emf.compare.diff.metamodel.AttributeChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.AttributeChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.AttributeOrderChange;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.diff.metamodel.DiffGroup;
+import org.eclipse.emf.compare.diff.metamodel.ModelElementChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.ModelElementChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.MoveModelElement;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeLeftTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceChangeRightTarget;
+import org.eclipse.emf.compare.diff.metamodel.ReferenceOrderChange;
+import org.eclipse.emf.compare.diff.metamodel.UpdateAttribute;
+import org.eclipse.emf.compare.diff.metamodel.UpdateReference;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.AttributeChangeLeftTargetTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.AttributeChangeRightTargetTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.AttributeOrderChangeTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.DiffGroupTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.ModelElementChangeLeftTargetTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.ModelElementChangeRightTargetTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.MoveModelElementTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.ReferenceChangeLeftTargetTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.ReferenceChangeRightTargetTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.ReferenceOrderChangeTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.UpdateAttributeTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.UpdateReferenceTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusCompareMap;
+import org.eclipse.papyrus.infra.emf.compare.diff.merge.ITransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.provider.ITransactionalMergerProvider;
+
+
+public class DefaultTransactionalMergerProvider implements ITransactionalMergerProvider {
+
+ /**
+ * This map keeps a bridge between a given {@link DiffElement}'s class and the most accurate merger's
+ * class for that particular {@link DiffElement}.
+ */
+ private Map<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> mergerTypes;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diff.merge.IMergerProvider#getMergers()
+ */
+ public Map<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> getMergers() {
+ if(mergerTypes == null) {
+ mergerTypes = new PapyrusCompareMap<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>>();
+ mergerTypes.put(DiffGroup.class, DiffGroupTransactionalMerger.class);
+ mergerTypes.put(ModelElementChangeRightTarget.class, ModelElementChangeRightTargetTransactionalMerger.class);
+ mergerTypes.put(ModelElementChangeLeftTarget.class, ModelElementChangeLeftTargetTransactionalMerger.class);
+ mergerTypes.put(MoveModelElement.class, MoveModelElementTransactionalMerger.class);
+ mergerTypes.put(ReferenceChangeRightTarget.class, ReferenceChangeRightTargetTransactionalMerger.class);
+ mergerTypes.put(ReferenceChangeLeftTarget.class, ReferenceChangeLeftTargetTransactionalMerger.class);
+ mergerTypes.put(UpdateReference.class, UpdateReferenceTransactionalMerger.class);
+ mergerTypes.put(AttributeChangeRightTarget.class, AttributeChangeRightTargetTransactionalMerger.class);
+ mergerTypes.put(AttributeChangeLeftTarget.class, AttributeChangeLeftTargetTransactionalMerger.class);
+ mergerTypes.put(UpdateAttribute.class, UpdateAttributeTransactionalMerger.class);
+ mergerTypes.put(ReferenceOrderChange.class, ReferenceOrderChangeTransactionalMerger.class);
+ mergerTypes.put(AttributeOrderChange.class, AttributeOrderChangeTransactionalMerger.class);
+ //TODO DiffExtensionMerger : not used for the moment
+ //TODO DefaultExtensionMerger : not used for the moment
+ }
+ return mergerTypes;
+ }
+
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/CopyWithReferenceCommand.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/CopyWithReferenceCommand.java
new file mode 100644
index 00000000000..7a7114408fd
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/CopyWithReferenceCommand.java
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.util;
+
+import java.util.Collections;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.compare.diff.merge.EMFCompareEObjectCopier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+
+/**
+ *
+ * This command allows to copy an EObject getting the copy before the command execution. (copyCommand.getCommandResult().getReturnValue();)
+ * The references and the XMI_Dis are copied during the command excetion
+ *
+ */
+public class CopyWithReferenceCommand extends AbstractTransactionalCommand {
+
+ /**
+ * The copied used to do the copy
+ */
+ final EMFCompareEObjectCopier copier;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param domain
+ * the editing domain
+ * @param diff
+ * the diffElement
+ * @param eObjectToCopy
+ * the object to copy
+ */
+ public CopyWithReferenceCommand(final TransactionalEditingDomain domain, final EMFCompareEObjectCopier copier, final EObject eObjectToCopy) {
+ super(domain, "CopyWithReferenceCommand", Collections.EMPTY_LIST); //$NON-NLS-1$
+ this.copier = copier;
+ final EObject copiedElement;
+ if(copier.containsKey(eObjectToCopy)) {
+ //385289: [UML Compare] Bad result after merginf UMLStereotypeApplicationAddition/Removal
+ //in some case, the elements are copied and merged twice!
+ copiedElement = this.copier.get(eObjectToCopy);
+ } else {
+ copiedElement = this.copier.copy(eObjectToCopy);
+ }
+ final CommandResult result = CommandResult.newOKCommandResult(copiedElement);
+ setResult(result);
+ }
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ this.copier.copyReferences();
+ this.copier.copyXMIIDs();
+ return getCommandResult();
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareEObjectCopier.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareEObjectCopier.java
new file mode 100644
index 00000000000..3105d2fd810
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareEObjectCopier.java
@@ -0,0 +1,440 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.diff.merge.EMFCompareEObjectCopier;
+import org.eclipse.emf.compare.diff.metamodel.ComparisonResourceSnapshot;
+import org.eclipse.emf.compare.diff.metamodel.DiffModel;
+import org.eclipse.emf.compare.diff.metamodel.DiffResourceSet;
+import org.eclipse.emf.compare.match.metamodel.Match2Elements;
+import org.eclipse.emf.compare.match.metamodel.MatchElement;
+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.xmi.XMIResource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.PapyrusMergeCommandProvider;
+import org.eclipse.papyrus.infra.emf.utils.ResourceUtils;
+
+/**
+ *
+ * This class copies the code of {@link EMFCompareEObjectCopier}, to do the actions with EMFCommands
+ *
+ */
+public class PapyrusCompareEObjectCopier extends EMFCompareEObjectCopier {
+
+ /**
+ * the serial UID
+ */
+ private static final long serialVersionUID = -6723632034214667973L;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param diff
+ */
+ public PapyrusCompareEObjectCopier(final DiffResourceSet diff) {
+ super(diff);
+ throw new UnsupportedOperationException("not yet implemented");//we should initialize the map as it is done in the 2nd constructor //$NON-NLS-1$
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param diff
+ */
+ public PapyrusCompareEObjectCopier(final DiffModel diff) {
+ super(diff);
+ final EObject container = diff.eContainer();
+ if(container instanceof ComparisonResourceSnapshot) {
+ final ComparisonResourceSnapshot snapshot = (ComparisonResourceSnapshot)container;
+ final EList<MatchElement> matchedElements = snapshot.getMatch().getMatchedElements();
+ for(MatchElement current : matchedElements) {
+ if(current instanceof Match2Elements) {
+ initializeCopier((Match2Elements)current);
+
+ }
+ }
+ }
+ }
+
+ /**
+ * Initialize the copier with the couple of Object matched during the diff
+ * It is useful for comparison between stereotyped elements in the nested editor
+ * see bug 384490: [UML Compare] Comparison between stereotyped elements doesn't work in the nested Compare Editor
+ *
+ * @param matchElement
+ *
+ */
+ protected void initializeCopier(final Match2Elements matchElement) {
+ final EObject left = ((Match2Elements)matchElement).getLeftElement();
+ final EObject right = ((Match2Elements)matchElement).getRightElement();
+ put(left, right);
+ put(right, left);
+ for(final MatchElement current : matchElement.getSubMatchElements()) {
+ if(current instanceof Match2Elements) {
+ initializeCopier((Match2Elements)current);
+ }
+ }
+ }
+
+ /**
+ * Copy the XMi_ID only when the id doesn't exist in the target resource
+ *
+ * @see org.eclipse.emf.compare.diff.merge.EMFCompareEObjectCopier#copyXMIIDs()
+ *
+ */
+ @Override
+ public void copyXMIIDs() {
+ for(final Map.Entry<EObject, EObject> entry : entrySet()) {
+ final EObject original = entry.getKey();
+ final EObject copy = entry.getValue();
+ if(original.eResource() instanceof XMIResource && copy.eResource() instanceof XMIResource) {
+ final XMIResource originResource = (XMIResource)original.eResource();
+ final XMIResource copyResource = (XMIResource)copy.eResource();
+ if(originResource.getID(original) != null) {
+ if(original.eResource() == copy.eResource()) {
+ final String currentID = originResource.getID(original);
+ if(ResourceUtils.getAllResourceIds(copyResource).contains(currentID)) {
+ continue;
+ }
+ }
+ copyResource.setID(copy, originResource.getID(original));
+ final TreeIterator<EObject> originalIterator = original.eAllContents();
+ final TreeIterator<EObject> copyIterator = copy.eAllContents();
+ while(originalIterator.hasNext() && copyIterator.hasNext()) {
+ final EObject nextOriginalChild = originalIterator.next();
+ final EObject nextCopyChild = copyIterator.next();
+ if(nextOriginalChild.eResource() == nextCopyChild.eResource()) {
+ final String currentID = originResource.getID(nextOriginalChild);
+ if(ResourceUtils.getAllResourceIds(copyResource).contains(currentID)) {
+ continue;
+ }
+ }
+ copyResource.setID(nextCopyChild, originResource.getID(nextOriginalChild));
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Adapted from copyReferenceValue(EReference targetReference, EObject target, EObject value,
+ * EObject matchedValue, int index)
+ *
+ * @param targetReference
+ * @param target
+ * @param value
+ * @param matchedValue
+ * @param index
+ * @return
+ */
+ public Command getCopyReferenceValueCommand(final TransactionalEditingDomain domain, final EReference targetReference, final EObject target, final EObject value, final EObject matchedValue, final int index) {
+ EObject actualValue = value;
+ if(value == null && matchedValue != null) {
+ // handleLinkedResourceDependencyChange(matchedValue);
+ // actualValue = get(matchedValue);
+ //TODO
+ throw new UnsupportedOperationException("Not yet supported"); //$NON-NLS-1$
+ }
+ if(matchedValue != null) {
+ put(actualValue, matchedValue);
+
+ final Object referenceValue = target.eGet(targetReference);
+ if(referenceValue instanceof Collection<?>) {
+ //tested with ReferenceChangeLefttargetExample
+ return getAddAtIndexCommand(domain, target, targetReference, (Collection<EObject>)referenceValue, matchedValue, index);
+
+ } else {
+ //target.eSet(targetReference, matchedValue);
+ //tested with the project UpdateReferenceExample2
+ return PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, target, targetReference, matchedValue);
+ }
+ }
+ //tested with ReferenceChangeLefttargetExample2
+ return getCopyValueReferenceCommand(domain, targetReference, target, actualValue, index);
+ }
+
+ private Command getCopyValueReferenceCommand(final TransactionalEditingDomain domain, final EReference targetReference, final EObject target, final EObject value, final int index) {
+ final Command copyValueCommand = new GMFtoEMFCommandWrapper(new AbstractTransactionalCommand(domain, "", null) { //$NON-NLS-1$
+
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ final EObject copy;
+ final EObject targetValue = PapyrusCompareEObjectCopier.this.get(value);
+ if(targetValue != null) {
+ copy = targetValue;
+ } else {
+ if(value.eResource() == null || value.eResource().getURI().isPlatformPlugin()) {
+ // We can't copy that object
+ copy = value;
+ } else {
+ copy = PapyrusCompareEObjectCopier.this.copy(value);
+ }
+ }
+ Command cmd = null;
+ final Object referenceValue = target.eGet(targetReference);
+ if(referenceValue instanceof List && targetReference.isMany()) {
+ if(copy.eIsProxy() && copy instanceof InternalEObject) {
+ // only add if the element is not already there.
+ final URI proxURI = ((InternalEObject)copy).eProxyURI();
+ boolean found = false;
+ final Iterator<EObject> it = ((List<EObject>)referenceValue).iterator();
+ while(!found && it.hasNext()) {
+ final EObject obj = it.next();
+ if(obj instanceof InternalEObject) {
+ found = proxURI.equals(((InternalEObject)obj).eProxyURI());
+ }
+ }
+ if(!found) {
+ final List<EObject> targetList = (List<EObject>)referenceValue;
+ //addAtIndex(targetList, copy, index);
+ //not tested
+ cmd = getAddAtIndexCommand(domain, target, targetReference, targetList, copy, index);
+ }
+ } else {
+ final List<EObject> targetList = (List<EObject>)referenceValue;
+ final int currentIndex = targetList.indexOf(copy);
+ if(currentIndex == -1) {
+ //addAtIndex(targetList, copy, index);
+ //not tested
+ cmd = getAddAtIndexCommand(domain, target, targetReference, targetList, copy, index);
+ } else {
+ // The order could be wrong in case of eOpposites
+ // movetoIndex(targetList, currentIndex, index);
+ cmd = getMoveAtIndexCommand(domain, target, targetList, targetReference, copy, currentIndex, index);
+ // throw new UnsupportedOperationException("Not yet supported");
+ }
+ }
+ } else {
+ if(copy.eIsProxy() && copy instanceof InternalEObject) {
+ // only change value if the URI changes
+ final URI proxURI = ((InternalEObject)copy).eProxyURI();
+ if(referenceValue instanceof InternalEObject) {
+ if(!proxURI.equals(((InternalEObject)referenceValue).eProxyURI())) {
+ //not tested
+ //target.eSet(targetReference, copy);
+ cmd = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, target, targetReference, copy);
+ }
+ }
+ } else {
+ //not tested
+ //target.eSet(targetReference, copy);
+ cmd = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, target, targetReference, copy);
+ }
+ }
+
+ if(cmd != null) {
+ cmd.execute();
+ }
+ return CommandResult.newOKCommandResult();
+ }
+
+ });
+ return copyValueCommand;
+ }
+
+ /**
+ *
+ * @param key
+ * @return
+ * the copied object
+ */
+ public EObject getCopiedValue(final EObject key) {
+ return get(key);
+ }
+
+
+ private Command getMoveAtIndexCommand(final TransactionalEditingDomain domain, final EObject target, final List<EObject> targetList, final EReference targetReference, final EObject copy, final int currentIndex, final int expectedIndex) {
+ final List<EObject> newColl = new ArrayList<EObject>(targetList);
+ final int size = targetList.size();
+ if(size <= 1 || currentIndex < 0 || currentIndex >= size) {
+ // return;
+ //do nothing
+ } else if(expectedIndex != -1 && expectedIndex != currentIndex && expectedIndex <= size - 1) {
+ newColl.add(expectedIndex, newColl.remove(currentIndex));
+ }
+
+ return PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, target, targetReference, newColl);
+ }
+
+ /**
+ * Returns the command to set the wanted object at the wanted index
+ *
+ * @param domain
+ * @param editedElement
+ * @param feature
+ * @param collection
+ * @param newValue
+ * @param index
+ * @return
+ */
+ private Command getAddAtIndexCommand(final TransactionalEditingDomain domain, final EObject editedElement, final EStructuralFeature feature, final Collection<EObject> collection, final EObject newValue, final int index) {
+ final List<EObject> newColl = new ArrayList<EObject>(collection);
+ final int listSize = collection.size();
+ if(index > -1 && index < listSize) {
+ newColl.add(index, newValue);
+ } else {
+ newColl.add(newValue);
+ }
+ attachRealPositionEAdapter(newValue, index);
+ reorderList(newColl);
+ return PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, editedElement, feature, newColl);
+ }
+
+ /**
+ * Duplicate code from EFactory
+ * If we could not merge a given object at its expected position in a list, we'll attach an Adapter to it
+ * in order to "remember" that "expected" position. That will allow us to reorder the list later on if
+ * need be.
+ *
+ * @param object
+ * The object on which to attach an Adapter.
+ * @param expectedPosition
+ * The expected position of <code>object</code> in its list.
+ */
+ private void attachRealPositionEAdapter(final Object object, final int expectedPosition) {
+ if(object instanceof EObject) {
+ ((EObject)object).eAdapters().add(new PositionAdapter(expectedPosition));
+ }
+ }
+
+ /**
+ * Duplicate code from EFactory
+ * Reorders the given list if it contains EObjects associated with a PositionAdapter which are not located
+ * at their expected positions.
+ *
+ * @param list
+ * The list that is to be reordered.
+ * @param <T>
+ * type of the list's elements.
+ */
+ private <T> void reorderList(final List<T> list) {
+ final List<T> newList = new ArrayList<T>(list);
+ Collections.sort(newList, new EObjectComparator());
+ for(int i = 0; i < list.size(); i++) {
+ int oldIndex = list.indexOf(newList.get(i));
+ list.add(i, list.remove(oldIndex));
+ }
+ return;
+ }
+
+
+ /**
+ * This class exists in several classes of this plugin. It is not an error : the same obejct can be referenced by different
+ * feature and different position at the same time. So we need to have a class PositionAdapter for each context!
+ * duplicate code from Efactory
+ * This adapter will be used to remember the accurate position of an EObject in its target list.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+ private class PositionAdapter extends AdapterImpl {
+
+ /** The index at which we expect to find this object. */
+ private final int expectedIndex;
+
+ /**
+ * Creates our adapter.
+ *
+ * @param index
+ * The index at which we expect to find this object.
+ */
+ public PositionAdapter(final int index) {
+ this.expectedIndex = index;
+ }
+
+ /**
+ * Returns the index at which we expect to find this object.
+ *
+ * @return The index at which we expect to find this object.
+ */
+ public int getExpectedIndex() {
+ return expectedIndex;
+ }
+ }
+
+ /**
+ *
+ * This class allows to compare EObject using the PositionAdapter.
+ *
+ *
+ */
+ private class EObjectComparator<T> implements Comparator<T> {
+
+ /**
+ *
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ *
+ * @param o1
+ * @param o2
+ * @return
+ */
+ public int compare(final T o1, final T o2) {
+ if(o1 instanceof EObject && o2 instanceof EObject) {
+ final int position1 = getWantedPosition((EObject)o1);
+ final int position2 = getWantedPosition((EObject)o2);
+ if(position1 != -1 && position2 != -1) {
+ return position1 - position2;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ *
+ * @param obj1
+ * an EObject
+ * @return
+ * the wanted position for this object
+ */
+ private int getWantedPosition(final EObject obj1) {
+ final Iterator<Adapter> adapters = obj1.eAdapters().iterator();
+ int expectedIndex = -1;
+ while(expectedIndex == -1 && adapters.hasNext()) {
+ final Adapter adapter = adapters.next();
+ if(adapter instanceof PositionAdapter) {
+ expectedIndex = ((PositionAdapter)adapter).getExpectedIndex();
+ }
+ }
+ return expectedIndex;
+ }
+
+ }
+
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareMap.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareMap.java
new file mode 100644
index 00000000000..a48c4b4d68e
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusCompareMap.java
@@ -0,0 +1,104 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.papyrus.infra.emf.compare.diff.Activator;
+
+/**
+ * This map log an error when a wanted element is unknown in the map
+ *
+ * @author VL222926
+ *
+ * @param <K>
+ * @param <V>
+ */
+public class PapyrusCompareMap<K, V> extends HashMap<K, V> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and load factor.
+ *
+ * @param initialCapacity
+ * The initial capacity.
+ * @param loadFactor
+ * The load factor.
+ * @throws IllegalArgumentException
+ * if the initial capacity is negative
+ * or the load factor is nonpositive.
+ */
+ public PapyrusCompareMap(final int initialCapacity, final float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and the default load factor (0.75).
+ *
+ * @param initialCapacity
+ * the initial capacity.
+ * @throws IllegalArgumentException
+ * if the initial capacity is negative.
+ */
+ public PapyrusCompareMap(final int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public PapyrusCompareMap() {
+ super();
+ }
+
+ /**
+ * Constructs a new <tt>HashMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
+ * default load factor (0.75) and an initial capacity sufficient to
+ * hold the mappings in the specified <tt>Map</tt>.
+ *
+ * @param m
+ * the map whose mappings are to be placed in this map.
+ * @throws NullPointerException
+ * if the specified map is null.
+ */
+ public PapyrusCompareMap(final Map<? extends K, ? extends V> m) {
+ super(m);
+ }
+
+ /**
+ * We display an error when a wanted element is not included in the Map
+ *
+ * @see java.util.HashMap#get(java.lang.Object)
+ *
+ * @param key
+ * @return
+ */
+ @Override
+ public V get(final Object key) {
+ V obj = super.get(key);
+ if(obj == null) {
+ Activator.log.error("The following element is unknown in the map : " + key, new NullPointerException()); //$NON-NLS-1$
+ }
+ return obj;
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusEFactory.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusEFactory.java
new file mode 100644
index 00000000000..0bb27cd9442
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/internal/util/PapyrusEFactory.java
@@ -0,0 +1,297 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.internal.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.compare.EMFCompareMessages;
+import org.eclipse.emf.compare.FactoryException;
+import org.eclipse.emf.compare.util.EFactory;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.PapyrusMergeCommandProvider;
+
+//TODO : merge with thepapyrus table command factory?
+/**
+ *
+ * This class is adapted from {@link EFactory}
+ *
+ */
+/**
+ *
+ * This class is adapted from {@link EFactory}
+ *
+ */
+public class PapyrusEFactory {
+
+
+ private PapyrusEFactory() {
+ //nothing to do
+ }
+
+ public static final <T> Command getEAddCommand(final TransactionalEditingDomain domain, final EObject object, final String name, final T arg) throws FactoryException {
+ return getEAddCommand(domain, object, name, arg, -1);
+ }
+
+ public static final <T> Command getEAddCommand(final TransactionalEditingDomain domain, final EObject object, final String name, final T arg, final int elementIndex) throws FactoryException {
+ return getEAddCommand(domain, object, name, arg, elementIndex, false);
+ }
+
+ public static final <T> Command getEAddCommand(final TransactionalEditingDomain domain, final EObject object, final String name, final T arg, final int elementIndex, final boolean reorder) throws FactoryException {
+ Command returnedCommand = null;
+ final EStructuralFeature feature = eStructuralFeature(object, name);
+ if(feature.isMany() && arg != null) {
+ final Object manyValue = object.eGet(feature);
+ // if (manyValue instanceof InternalEList<?>) {
+ // final InternalEList<? super T> internalEList = (InternalEList<? super T>)manyValue;
+ // final int listSize = internalEList.size();
+ // if (elementIndex > -1 && elementIndex < listSize) {
+ // internalEList.addUnique(elementIndex, arg);
+ // } else {
+ // internalEList.addUnique(arg);
+ // }
+ // if (reorder) {
+ // attachRealPositionEAdapter(arg, elementIndex);
+ // reorderList(internalEList);
+ // }
+ // } else if (manyValue instanceof List<?>) {
+ // final List<? super T> list = (List<? super T>)manyValue;
+ // final int listSize = list.size();
+ // if (elementIndex > -1 && elementIndex < listSize) {
+ // list.add(elementIndex, arg);
+ // } else {
+ // list.add(arg);
+ // }
+ // if (reorder) {
+ // attachRealPositionEAdapter(arg, elementIndex);
+ // reorderList(list);
+ // }
+ // } else if (manyValue instanceof Collection<?>) {
+ // ((Collection<? super T>)manyValue).add(arg);
+ // }
+
+ if(manyValue instanceof Collection<?>) {
+ List<Object> newValue = new ArrayList<Object>((Collection<?>)manyValue);
+ final int listSize = newValue.size();
+ if(manyValue instanceof List<?>) {
+ if(elementIndex > -1 && elementIndex < listSize) {
+ newValue.add(elementIndex, arg);
+ } else {
+ newValue.add(arg);
+ }
+ if(reorder) {
+ attachRealPositionEAdapter(arg, elementIndex);
+ reorderList((List<?>)newValue);
+ }
+ } else if(manyValue instanceof Collection<?>) {
+ newValue.add(arg);
+ }
+ returnedCommand = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, object, feature, newValue);
+ }
+ } else if(!feature.isMany()) {
+ // eSet(object, name, arg);
+ returnedCommand = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, object, feature, arg);
+ }
+ return returnedCommand;
+ }
+
+ //TODO not tested
+ public static final Command getERemoveCommand(final TransactionalEditingDomain domain, final EObject object, final String name, final Object arg) throws FactoryException {
+ // final Object list = object.eGet(eStructuralFeature(object, name));
+ // if (list instanceof List) {
+ // if (arg != null) {
+ // ((List<?>)list).remove(arg);
+ // }
+ // } else {
+ // eSet(object, name, null);
+ // }
+ final Object list = object.eGet(eStructuralFeature(object, name));
+ if(list instanceof List) {
+ if(arg != null) {
+ List<?> newValue = new ArrayList((List<?>)list);
+ ((List<?>)newValue).remove(arg);
+ return getESetCommand(domain, object, name, newValue);
+ }
+ } else {
+ return getESetCommand(domain, object, name, null);
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param object
+ * @param name
+ * @param arg
+ * @return
+ * @throws FactoryException
+ */
+ public static final Command getESetCommand(final TransactionalEditingDomain domain, final EObject object, final String name, final Object arg) throws FactoryException {
+ Command returnedCommand;
+ final EStructuralFeature feature = eStructuralFeature(object, name);
+ if(!feature.isChangeable())
+ throw new FactoryException(EMFCompareMessages.getString("EFactory.UnSettableFeature", name)); //$NON-NLS-1$
+
+ if(feature.getEType() instanceof EEnum && arg instanceof String) {
+ final EEnumLiteral literal = ((EEnum)feature.getEType()).getEEnumLiteral((String)arg);
+ //object.eSet(feature, literal);
+ returnedCommand = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, object, feature, literal);
+ } else {
+ if(arg == null && feature.isMany()) {
+ //object.eSet(feature, Collections.EMPTY_LIST);
+ returnedCommand = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, object, feature, Collections.EMPTY_LIST);
+ } else if(arg == null) {
+ //object.eSet(feature, feature.getDefaultValue());
+ returnedCommand = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, object, feature, feature.getDefaultValue());
+ } else {
+ //object.eSet(feature, arg);
+ returnedCommand = PapyrusMergeCommandProvider.INSTANCE.getSetCommand(domain, object, feature, arg);
+ }
+ }
+ return returnedCommand;
+ }
+
+
+ public static EStructuralFeature eStructuralFeature(final EObject object, final String name) throws FactoryException {
+ return EFactory.eStructuralFeature(object, name);
+ }
+
+ /**
+ * Duplicate code from EFactory
+ * If we could not merge a given object at its expected position in a list, we'll attach an Adapter to it
+ * in order to "remember" that "expected" position. That will allow us to reorder the list later on if
+ * need be.
+ *
+ * @param object
+ * The object on which to attach an Adapter.
+ * @param expectedPosition
+ * The expected position of <code>object</code> in its list.
+ */
+ private static void attachRealPositionEAdapter(final Object object, final int expectedPosition) {
+ if(object instanceof EObject) {
+ ((EObject)object).eAdapters().add(new PositionAdapter(expectedPosition));
+ }
+ }
+
+ /**
+ * Reorders the given list if it contains EObjects associated with a PositionAdapter which are not located
+ * at their expected positions.
+ *
+ * @param list
+ * The list that is to be reordered.
+ * @param <T>
+ * type of the list's elements.
+ */
+ private static <T> void reorderList(final List<T> list) {
+ List<T> newList = new ArrayList<T>(list);
+ Collections.sort(newList, new EObjectComparator());
+ for(int i = 0; i < list.size(); i++) {
+ int oldIndex = list.indexOf(newList.get(i));
+ list.add(i, list.remove(oldIndex));
+ }
+ return;
+ }
+
+
+ /**
+ * duplicate code from Efactory
+ * This adapter will be used to remember the accurate position of an EObject in its target list.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+ private static class PositionAdapter extends AdapterImpl {
+
+ /** The index at which we expect to find this object. */
+ private final int expectedIndex;
+
+ /**
+ * Creates our adapter.
+ *
+ * @param index
+ * The index at which we expect to find this object.
+ */
+ public PositionAdapter(final int index) {
+ this.expectedIndex = index;
+ }
+
+ /**
+ * Returns the index at which we expect to find this object.
+ *
+ * @return The index at which we expect to find this object.
+ */
+ public int getExpectedIndex() {
+ return expectedIndex;
+ }
+ }
+
+ /**
+ *
+ * This class allows to compare EObject using the PositionAdapter.
+ *
+ *
+ */
+ private static class EObjectComparator<T> implements Comparator<T> {
+
+ /**
+ *
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ *
+ * @param o1
+ * @param o2
+ * @return
+ */
+ public int compare(final T o1, final T o2) {
+ if(o1 instanceof EObject && o2 instanceof EObject) {
+ final int position1 = getWantedPosition((EObject)o1);
+ final int position2 = getWantedPosition((EObject)o2);
+ if(position1 != -1 && position2 != -1) {
+ return position1 - position2;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ *
+ * @param obj1
+ * an EObject
+ * @return
+ * the wanted position for this object
+ */
+ private int getWantedPosition(final EObject obj1) {
+ final Iterator<Adapter> adapters = obj1.eAdapters().iterator();
+ int expectedIndex = -1;
+ while(expectedIndex == -1 && adapters.hasNext()) {
+ final Adapter adapter = adapters.next();
+ if(adapter instanceof PositionAdapter) {
+ expectedIndex = ((PositionAdapter)adapter).getExpectedIndex();
+ }
+ }
+ return expectedIndex;
+ }
+
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/merge/ITransactionalMerger.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/merge/ITransactionalMerger.java
new file mode 100644
index 00000000000..2a34daeba32
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/merge/ITransactionalMerger.java
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.merge;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.diff.merge.DefaultMerger;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+
+
+/**
+ *
+ * The mergers which implement this interface are able to provide commands for the merge actions
+ *
+ */
+public interface ITransactionalMerger {
+
+ /**
+ * This command should have the same behavior as {@link DefaultMerger#applyInOrigin()}
+ *
+ * @param alreadyManaged
+ * the list of the DiffElement already managed buy the command that we are creating
+ * @return
+ * the command to do the action
+ */
+ public Command getApplyInOriginCommand(final TransactionalEditingDomain domain, final Collection<DiffElement> alreadyManaged);
+
+ /**
+ * This command should have the same behavior as {@link DefaultMerger#undoInTarget()}
+ *
+ * @param domain
+ * @param alreadyManaged
+ * the list of the DiffElement already managed buy the command that we are creating
+ * @return
+ * the command to do the action
+ */
+ public Command getUndoInTargetCommand(final TransactionalEditingDomain domain, final Collection<DiffElement> alreadyManaged);
+
+ /**
+ * This command should have the same behavior as {@link DefaultMerger#doApplyInOrigin}
+ *
+ * @param domain
+ * @return
+ * the command to do the action
+ */
+ public Command getDoApplyInOriginCommand(final TransactionalEditingDomain domain);
+
+ /**
+ * This command should have the same behavior as {@link DefaultMerger#doUndoInTarget}
+ *
+ * @param domain
+ * @return
+ * the command to do the action
+ */
+ public Command getDoUndoInTargetCommand(final TransactionalEditingDomain domain);
+
+ /**
+ * This command should have the same behavior as {@link DefaultMerger#mergeRequiredDifferences}
+ *
+ * @param domain
+ * @param applyInOrigin
+ * @param alreadyManaged
+ * the list of the DiffElement already managed buy the command that we are creating
+ * @return
+ * the command to do the action
+ */
+ public Command getMergeRequiredDifferencesCommand(final TransactionalEditingDomain domain, final boolean applyInOrigin, final Collection<DiffElement> alreadyManaged);
+
+ /**
+ * This command should have the same behavior as {@link DefaultMerger#postProcess}
+ *
+ * @param domain
+ * @return
+ * the command to do the action
+ */
+ public Command getPostProcessCommand(final TransactionalEditingDomain domain);
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the command can be executed, <code>false</code> if not
+ */
+ public boolean canApplyInOrigin();
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the command can be executed, <code>false</code> if not
+ */
+ public boolean canUndoInTarget();
+
+
+ /**
+ * Sets the {@link DiffElement} to be merged.
+ *
+ * @param element
+ * The {@link DiffElement} to be merged.
+ */
+ void setDiffElement(DiffElement element);
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/provider/ITransactionalMergerProvider.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/provider/ITransactionalMergerProvider.java
new file mode 100644
index 00000000000..9481746f3ed
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/provider/ITransactionalMergerProvider.java
@@ -0,0 +1,25 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.provider;
+
+import java.util.Map;
+
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.papyrus.infra.emf.compare.diff.merge.ITransactionalMerger;
+
+
+public interface ITransactionalMergerProvider {
+
+ Map<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> getMergers();
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/MergerProviderDescriptor.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/MergerProviderDescriptor.java
new file mode 100644
index 00000000000..93c35cfbe07
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/MergerProviderDescriptor.java
@@ -0,0 +1,222 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ * Adapted code from EMF-Compare
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.service;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.emf.compare.EMFComparePlugin;
+import org.eclipse.emf.compare.diff.EMFCompareDiffMessages;
+import org.eclipse.emf.compare.util.EngineConstants;
+import org.eclipse.papyrus.infra.emf.compare.diff.provider.ITransactionalMergerProvider;
+
+/**
+ * This descriptor represents a merger provider contribution via the extension point <code>org.eclipse.emf.compare.diff.mergerprovider</code>.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+/* package */class MergerProviderDescriptor implements Comparable<MergerProviderDescriptor> {
+
+ /** Configuration element of this descriptor. */
+ protected final IConfigurationElement element;
+
+ /** File extensions this merger takes into account. */
+ protected final String fileExtension;
+
+ /** Class name of the described merger provider. */
+ protected final String mergerProviderClassName;
+
+ /**
+ * Priority of this descriptor. Should be one of
+ * <ul>
+ * <li>{@link EngineConstants#PRIORITY_HIGHEST}</li>
+ * <li>{@link EngineConstants#PRIORITY_HIGH}</li>
+ * <li>{@link EngineConstants#PRIORITY_NORMAL}</li>
+ * <li>{@link EngineConstants#PRIORITY_LOW}</li>
+ * <li>{@link EngineConstants#PRIORITY_LOWEST}</li>
+ * </ul>
+ */
+ protected final String priority;
+
+ /** {@link IMergerProvider} this descriptor describes. */
+ private ITransactionalMergerProvider mergerProvider;
+
+ /**
+ * Instantiate the descriptor given its configuration.
+ *
+ * @param configuration
+ * {@link IConfigurationElement Configuration element} of this descriptor.
+ */
+ public MergerProviderDescriptor(IConfigurationElement configuration) {
+ element = configuration;
+ fileExtension = getAttribute("fileExtension", "*"); //$NON-NLS-1$ //$NON-NLS-2$
+ priority = getAttribute("priority", "low"); //$NON-NLS-1$//$NON-NLS-2$
+ mergerProviderClassName = getAttribute("mergerProviderClass", null); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(MergerProviderDescriptor other) {
+ final int nombre1 = other.getPriorityValue(other.getPriority());
+ final int nombre2 = getPriorityValue(getPriority());
+ return nombre2 - nombre1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ boolean isEqual = true;
+ if(this == obj) {
+ isEqual = true;
+ } else if(obj == null || getClass() != obj.getClass()) {
+ isEqual = false;
+ } else if(obj instanceof MergerProviderDescriptor) {
+ final MergerProviderDescriptor other = (MergerProviderDescriptor)obj;
+ if(mergerProviderClassName == null && other.mergerProviderClassName != null) {
+ isEqual = false;
+ } else if(mergerProviderClassName != null && !mergerProviderClassName.equals(other.mergerProviderClassName)) {
+ isEqual = false;
+ } else if(fileExtension == null && other.fileExtension != null) {
+ isEqual = false;
+ } else if(fileExtension != null && !fileExtension.equals(other.fileExtension)) {
+ isEqual = false;
+ } else if(priority == null && other.priority != null) {
+ isEqual = false;
+ } else if(priority != null && !priority.equals(other.priority)) {
+ isEqual = false;
+ }
+ } else {
+ isEqual = false;
+ }
+ return isEqual;
+ }
+
+ /**
+ * Returns the file extension this engine should handle.
+ *
+ * @return The file extension this engine should handle.
+ */
+ public String getFileExtension() {
+ return fileExtension;
+ }
+
+ /**
+ * Returns the engine instance.
+ *
+ * @return The engine instance.
+ */
+ public ITransactionalMergerProvider getMergerProviderInstance() {
+ if(mergerProvider == null) {
+ try {
+ mergerProvider = (ITransactionalMergerProvider)element.createExecutableExtension("mergerProviderClass"); //$NON-NLS-1$
+ } catch (final CoreException e) {
+ EMFComparePlugin.log(e, false);
+ }
+ }
+ return mergerProvider;
+ }
+
+ /**
+ * Returns the engine priority.
+ *
+ * @return The engine priority.
+ */
+ public String getPriority() {
+ return priority.toLowerCase();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int classNameHash = 0;
+ if(mergerProviderClassName != null) {
+ classNameHash = mergerProviderClassName.hashCode();
+ }
+ int extensionHash = 0;
+ if(fileExtension != null) {
+ extensionHash = fileExtension.hashCode();
+ }
+ int priorityHash = 0;
+ if(priority != null) {
+ priorityHash = priority.hashCode();
+ }
+
+ return (((prime + classNameHash) * prime) + extensionHash) * prime + priorityHash;
+ }
+
+ /*
+ * created as package visibility method to allow access from MergeFactory
+ */
+ /**
+ * Returns the value of the priority described by the given {@link String}.<br/>
+ * Returned values according
+ * to <code>priorityString</code> value :
+ * <ul>
+ * <li>&quot;lowest&quot; =&gt; {@value EngineConstants#PRIORITY_LOWEST}</li>
+ * <li>&quot;low&quot; =&gt; {@value EngineConstants#PRIORITY_LOW}</li>
+ * <li>&quot;high&quot; =&gt; {@value EngineConstants#PRIORITY_HIGH}</li>
+ * <li>&quot;highest&quot; =&gt; {@value EngineConstants#PRIORITY_HIGHEST}</li>
+ * <li>anything else =&gt; {@value EngineConstants#PRIORITY_NORMAL}</li>
+ * </ul>
+ *
+ * @param priorityString
+ * {@link String} value of the priority we seek.
+ * @return <code>int</code> corresponding to the given priority {@link String}.
+ */
+ /* package */int getPriorityValue(String priorityString) {
+ if(priorityString == null)
+ throw new IllegalArgumentException(EMFCompareDiffMessages.getString("Descriptor.IllegalPriority")); //$NON-NLS-1$
+ int priorityValue = EngineConstants.PRIORITY_NORMAL;
+ if("lowest".equals(priorityString)) { //$NON-NLS-1$
+ priorityValue = EngineConstants.PRIORITY_LOWEST;
+ } else if("low".equals(priorityString)) { //$NON-NLS-1$
+ priorityValue = EngineConstants.PRIORITY_LOW;
+ } else if("high".equals(priorityString)) { //$NON-NLS-1$
+ priorityValue = EngineConstants.PRIORITY_HIGH;
+ } else if("highest".equals(priorityString)) { //$NON-NLS-1$
+ priorityValue = EngineConstants.PRIORITY_HIGHEST;
+ }
+ return priorityValue;
+ }
+
+ /**
+ * Returns the value of the attribute <code>name</code> of this descriptor's configuration element. if the
+ * attribute hasn't been set, we'll return <code>defaultValue</code> instead.
+ *
+ * @param name
+ * Name of the attribute we seek the value of.
+ * @param defaultValue
+ * Value to return if the attribute hasn't been set.
+ * @return The value of the attribute <code>name</code>, <code>defaultValue</code> if it hasn't been set.
+ */
+ private String getAttribute(String name, String defaultValue) {
+ final String value = element.getAttribute(name);
+ if(value != null)
+ return value;
+ if(defaultValue != null)
+ return defaultValue;
+ throw new IllegalArgumentException(EMFCompareDiffMessages.getString("Descriptor.MissingAttribute", name)); //$NON-NLS-1$
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeFactory.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeFactory.java
new file mode 100644
index 00000000000..2a2227f7611
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeFactory.java
@@ -0,0 +1,292 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.EMFPlugin;
+import org.eclipse.emf.compare.EMFComparePlugin;
+import org.eclipse.emf.compare.diff.merge.IMerger;
+import org.eclipse.emf.compare.diff.metamodel.AbstractDiffExtension;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.util.ClassUtils;
+import org.eclipse.emf.compare.util.EMFCompareMap;
+import org.eclipse.emf.compare.util.EngineConstants;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.DefaultTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.provider.DefaultTransactionalMergerProvider;
+import org.eclipse.papyrus.infra.emf.compare.diff.merge.ITransactionalMerger;
+
+
+/**
+ *
+ * replaces MergeFactory
+ *
+ */
+public class TransactionalMergeFactory {
+
+ /** Wild card for file extensions. */
+ private static final String ALL_EXTENSIONS = "*"; //$NON-NLS-1$
+
+ /** Remembers the last file extension for which we've populated {@link #MERGER_TYPES}. */
+ private static String lastExtension = ""; //$NON-NLS-1$
+
+ /** Name of the extension point to parse for merger providers. */
+ private static final String MERGER_PROVIDER_EXTENSION_POINT = "org.eclipse.papyrus.infra.emf.compare.diff.mergerprovider"; //$NON-NLS-1$
+
+ /**
+ * This map will be populated with the merger associated to given {@link DiffElement}s. Each diff element
+ * will be mapped to the merger provided by the MergerProvider contributed with the highest priority.
+ */
+ private static final Map<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> MERGER_TYPES = new EMFCompareMap<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>>();
+
+ /** Keeps track of all the providers we've parsed. */
+ private static final Map<String, ArrayList<MergerProviderDescriptor>> PARSED_PROVIDERS = new EMFCompareMap<String, ArrayList<MergerProviderDescriptor>>();
+
+ /** Externalized here to avoid too many distinct usages. */
+ private static final String TAG_PROVIDER = "mergerprovider"; //$NON-NLS-1$
+
+ /** These are the possible priorities for the provided mergers. */
+ private static final int[] MERGER_PRIORITIES = { EngineConstants.PRIORITY_LOWEST, EngineConstants.PRIORITY_LOW, EngineConstants.PRIORITY_NORMAL, EngineConstants.PRIORITY_HIGH, EngineConstants.PRIORITY_HIGHEST, };
+
+ static {
+ parseExtensionMetadata();
+ }
+
+ /**
+ * Utility classes don't need to (and shouldn't) be instantiated.
+ */
+ private TransactionalMergeFactory() {
+ // prevents instantiation
+ }
+
+ /**
+ * Handles the creation of the merger for a given {@link DiffElement}.
+ *
+ * @param element
+ * {@link DiffElement} for which we need a merger.
+ * @return The merger adapted to <code>element</code>, <code>null</code> if it cannot be instantiated.
+ */
+ public static ITransactionalMerger createMerger(DiffElement element) {
+ // If the merger provides a default constructor, we instantiate it
+ ITransactionalMerger elementMerger = null;
+
+
+ //EMF-Compare implementation
+ // if (element instanceof AbstractDiffExtension) {
+ // elementMerger = ((AbstractDiffExtension)element).provideMerger();
+ // if (elementMerger == null) {
+ // elementMerger = new DefaultExtensionMerger();
+ // }
+ // }
+
+ // Papyrus EMF-Compare Implementation
+ if(element instanceof AbstractDiffExtension) {
+ try {
+ IMerger merger = ((AbstractDiffExtension)element).provideMerger();
+ if(merger != null) {
+ if(merger instanceof ITransactionalMerger) {
+ elementMerger = (ITransactionalMerger)merger;
+ }
+ }
+ } catch (UnsupportedOperationException e) {
+ //we ignore the exception, this exception comes from the Generated Code when the developper don't use Generated NOT
+ }
+ }
+ //TODO : and the default extension merger ?
+
+ if(elementMerger == null) {
+ try {
+ final Class<? extends ITransactionalMerger> mergerClass = getBestMerger(element);
+ elementMerger = mergerClass.newInstance();
+ } catch (final InstantiationException e) {
+ EMFComparePlugin.log(e.getMessage(), false);
+ } catch (final IllegalAccessException e) {
+ EMFComparePlugin.log(e.getMessage(), false);
+ }
+ }
+
+ if(elementMerger != null) {
+ elementMerger.setDiffElement(element);
+ }
+ //cf bug 396267: [UML Compare] it is not possible to merge a difference on a stereotype property
+ //Assert.isNotNull(elementMerger, NLS.bind("Merger for {0} not found", element));
+ Assert.isNotNull(elementMerger, NLS.bind("Merger for {0} not found", element.getClass()));
+ return elementMerger;
+ }
+
+ /**
+ * Returns the merger class that is best suited for the given {@link DiffElement}. Merger classes can be
+ * managed via {@link #addMergerType(Class, Class)} and {@link #removeMergerType(Class)}.
+ *
+ * @param element
+ * {@link DiffElement} we want a merger for.
+ * @return The merger class that is best suited for the given {@link DiffElement}.
+ */
+ private static Class<? extends ITransactionalMerger> getBestMerger(DiffElement element) {
+ Class<? extends ITransactionalMerger> mergerClass = DefaultTransactionalMerger.class;
+
+ EObject rightElement = (EObject)ClassUtils.invokeMethod(element, "getRightElement"); //$NON-NLS-1$
+ if(rightElement == null) {
+ rightElement = (EObject)ClassUtils.invokeMethod(element, "getRightParent"); //$NON-NLS-1$
+ }
+ String resourceFileExtension = null;
+ if(rightElement != null && rightElement.eResource() != null) {
+ resourceFileExtension = rightElement.eResource().getURI().fileExtension();
+ }
+
+ if(resourceFileExtension == null) {//Papyrus code
+ EObject leftElement = (EObject)ClassUtils.invokeMethod(element, "getLeftElement"); //$NON-NLS-1$
+ if(leftElement == null) {
+ leftElement = (EObject)ClassUtils.invokeMethod(element, "getLeftParent"); //$NON-NLS-1$
+ }
+
+ if(leftElement != null && leftElement.eResource() != null) {
+ resourceFileExtension = leftElement.eResource().getURI().fileExtension();
+ }
+ }
+
+ if(resourceFileExtension == null) {
+ resourceFileExtension = ALL_EXTENSIONS;
+ }
+
+ final Map<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> mergersMap;
+ if(EMFPlugin.IS_ECLIPSE_RUNNING) {
+ mergersMap = getMergerTypes(resourceFileExtension);
+ } else {
+ mergersMap = MERGER_TYPES;
+ }
+
+ // If we know the merger for this class, we return it
+ if(mergersMap.containsKey(element.getClass())) {
+ mergerClass = mergersMap.get(element.getClass());
+ // Else we seek through the map if our element is an instance of one of the class keys.
+ } else {
+ for(final Entry<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> entry : mergersMap.entrySet()) {
+ if(entry.getKey().isInstance(element)) {
+ mergerClass = entry.getValue();
+ break;
+ }
+ }
+ }
+ return mergerClass;
+ }
+
+ /**
+ * This will iterate through the list of the parsed providers from the lowest to the highest priority and
+ * associate each known {@link DiffElement} to a merger in order of their provider's priority.
+ *
+ * @param fileExtension
+ * File extension on which the provider can apply its mergers.
+ * @return The map of the merger associated to given {@link DiffElement}s.
+ */
+ private static Map<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> getMergerTypes(String fileExtension) {
+ if(!fileExtension.equals(lastExtension)) {
+ lastExtension = fileExtension;
+ MERGER_TYPES.clear();
+ /*
+ * TODO We'll iterate n times over all the parsed providers (one loop for each priority). See if
+ * we can optimize this.
+ */
+ for(final int priority : MERGER_PRIORITIES) {
+ final Map<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>> mergers = new EMFCompareMap<Class<? extends DiffElement>, Class<? extends ITransactionalMerger>>();
+ // Iterates through the list of providers registered for all extensions
+ if(PARSED_PROVIDERS.containsKey(ALL_EXTENSIONS)) {
+ final List<MergerProviderDescriptor> list = PARSED_PROVIDERS.get(ALL_EXTENSIONS);
+ Collections.sort(list);
+ for(final MergerProviderDescriptor descriptor : list) {
+ if(descriptor.getPriorityValue(descriptor.priority) == priority) {
+ mergers.putAll(descriptor.getMergerProviderInstance().getMergers());
+ }
+ }
+ }
+ if(PARSED_PROVIDERS.containsKey(fileExtension)) {
+ final List<MergerProviderDescriptor> list = PARSED_PROVIDERS.get(fileExtension);
+ Collections.sort(list);
+ for(final MergerProviderDescriptor descriptor : list) {
+ if(descriptor.getPriorityValue(descriptor.priority) == priority) {
+ mergers.putAll(descriptor.getMergerProviderInstance().getMergers());
+ }
+ }
+ }
+ MERGER_TYPES.putAll(mergers);
+ }
+ }
+ return MERGER_TYPES;
+ }
+
+ /**
+ * This will parse the currently running platform for extensions and store all the diff engines and diff
+ * extensions that can be found.
+ */
+ private static void parseExtensionMetadata() {
+ if(EMFPlugin.IS_ECLIPSE_RUNNING) {
+ final IExtension[] extensions = Platform.getExtensionRegistry().getExtensionPoint(MERGER_PROVIDER_EXTENSION_POINT).getExtensions();
+ for(int i = 0; i < extensions.length; i++) {
+ final IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
+ for(int j = 0; j < configElements.length; j++) {
+ final MergerProviderDescriptor desc = parseProvider(configElements[j]);
+ storeProviderDescriptor(desc);
+ }
+ }
+ } else {
+ MERGER_TYPES.putAll(new DefaultTransactionalMergerProvider().getMergers());
+ }
+ }
+
+ /**
+ * This will parse the given {@link IConfigurationElement configuration element} and return a descriptor
+ * for it if it describes a merger provider.
+ *
+ * @param configElement
+ * Configuration element to parse.
+ * @return {@link MergerProviderDescriptor} wrapped around <code>configElement</code> if it describes a
+ * merger provider, <code>null</code> otherwise.
+ */
+ private static MergerProviderDescriptor parseProvider(IConfigurationElement configElement) {
+ if(!configElement.getName().equals(TAG_PROVIDER))
+ return null;
+ final MergerProviderDescriptor desc = new MergerProviderDescriptor(configElement);
+ return desc;
+ }
+
+ /**
+ * Stores the given descriptor in the list of known {@link MergerProviderDescriptor}s.
+ *
+ * @param desc
+ * Descriptor to be added to the list of all know descriptors.
+ */
+ private static void storeProviderDescriptor(MergerProviderDescriptor desc) {
+ if(desc.getFileExtension() == null)
+ return;
+
+ final String[] extensions = desc.getFileExtension().split(","); //$NON-NLS-1$
+ for(final String mergerExtension : extensions) {
+ if(!PARSED_PROVIDERS.containsKey(mergerExtension)) {
+ PARSED_PROVIDERS.put(mergerExtension, new ArrayList<MergerProviderDescriptor>());
+ }
+ final List<MergerProviderDescriptor> set = PARSED_PROVIDERS.get(mergerExtension);
+ set.add(desc);
+ }
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeService.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeService.java
new file mode 100644
index 00000000000..438190c7724
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/service/TransactionalMergeService.java
@@ -0,0 +1,466 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.compare.diff.merge.EMFCompareEObjectCopier;
+import org.eclipse.emf.compare.diff.merge.IMergeListener;
+import org.eclipse.emf.compare.diff.merge.IMerger;
+import org.eclipse.emf.compare.diff.merge.MergeEvent;
+import org.eclipse.emf.compare.diff.merge.service.MergeFactory;
+import org.eclipse.emf.compare.diff.metamodel.ConflictingDiffElement;
+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.DiffResourceSet;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.FireMergeDiffEndCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.FireMergeDiffStartCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.FireMergeOperationEndCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.command.FireMergeOperationStartCommand;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.merger.DiffGroupTransactionalMerger;
+import org.eclipse.papyrus.infra.emf.compare.diff.internal.util.PapyrusCompareEObjectCopier;
+import org.eclipse.papyrus.infra.emf.compare.diff.merge.ITransactionalMerger;
+
+
+
+/**
+ *
+ * This service should replace the EMF-Compare MergeService
+ *
+ */
+public class TransactionalMergeService {
+
+ // private static Method addMergeListenerMethod = null;
+ //
+ // private static Method removeMergeListenerMethod = null;
+
+ /** This copier will be used when merging references. */
+ private static EMFCompareEObjectCopier copier;
+
+ // private static Object copier;
+
+
+ /**
+ * Default constructor.
+ */
+ private TransactionalMergeService() {
+ // hides default constructor
+ }
+
+ // /**
+ // * TODO this method should be covered with a JUnit test
+ // * Registers a new merge listener for notifications about merge operations. Has no effect if the listener
+ // * is already registered.
+ // *
+ // * @param listener
+ // * New Listener to register for notifications.
+ // */
+ // public static void addMergeListener(final IMergeListener listener) {
+ // if(addMergeListenerMethod == null) {
+ // Class<?>[] parameterTypes = new Class[1];
+ // parameterTypes[0] = IMergeListener.class;
+ // try {
+ // addMergeListenerMethod = ReflectHelper.getMethod(MergeService.class, "addMergeListener", parameterTypes); //$NON-NLS-1$
+ // } catch (SecurityException e) {
+ // Activator.log.error(e);
+ // } catch (NoSuchMethodException e) {
+ // Activator.log.error(e);
+ // }
+ // }
+ // final Object[] parameters = new Object[1];
+ // parameters[0] = listener;
+ // try {
+ // addMergeListenerMethod.invoke(null, parameters);
+ // } catch (IllegalArgumentException e) {
+ // Activator.log.error(e);
+ // } catch (IllegalAccessException e) {
+ // Activator.log.error(e);
+ // } catch (InvocationTargetException e) {
+ // Activator.log.error(e);
+ // }
+ // }
+
+
+
+
+ public static Command getMergeCommand(final TransactionalEditingDomain domain, final DiffElement element, final boolean leftToRight) {
+ CompoundCommand cmd = new CompoundCommand("MergeCommand"); //$NON-NLS-1$
+ cmd.append(new FireMergeOperationStartCommand(element, getMergeListeners()));
+ cmd.append(getDoMergeCommand(domain, element, leftToRight));
+ cmd.append(new FireMergeOperationEndCommand(element, getMergeListeners()));
+ return cmd;
+ }
+
+
+
+ private static Command getDoMergeCommand(final TransactionalEditingDomain domain, final DiffElement element, final boolean leftToRight) {
+ final CompoundCommand cmd = new CompoundCommand("DoMergeCommand"); //$NON-NLS-1$
+ cmd.append(new FireMergeDiffStartCommand(element, getMergeListeners()));
+ final ITransactionalMerger merger;
+ //TODO post a bug to EMF-Compare -> we can't define our own merger for DiffGroup Element
+ if(element instanceof DiffGroup) {
+ merger = new DiffGroupTransactionalMerger();
+ merger.setDiffElement(element);
+ } else if(element instanceof ConflictingDiffElement) {
+ merger = TransactionalMergeFactory.createMerger(element.getSubDiffElements().get(0));
+ } else {
+ merger = TransactionalMergeFactory.createMerger(element);
+ }
+ final Collection<DiffElement> alreadyManaged = new ArrayList<DiffElement>();
+ if(merger instanceof ITransactionalMerger) {
+ if(leftToRight) {
+ cmd.append(((ITransactionalMerger)merger).getUndoInTargetCommand(domain, alreadyManaged));
+ } else {
+ cmd.append(((ITransactionalMerger)merger).getApplyInOriginCommand(domain, alreadyManaged));
+ }
+ } else {
+ throw new UnsupportedOperationException(NLS.bind("I can't found the Papyrus Merger for {0}.", element)); //$NON-NLS-1$
+ }
+ alreadyManaged.clear();
+ cmd.append(new FireMergeDiffEndCommand(element, getMergeListeners()));
+ return cmd;
+ }
+
+
+ /**
+ * Execute the command to merge The DiffElement
+ *
+ * @param domain
+ * the {@link TransactionalEditingDomain}
+ * @param element
+ * the DiffElement to merger
+ * @param leftToRight
+ * <code>True</code> if the changes must be applied from the left to the right model, <code>False</code> when they have to be applied the
+ * other way around.
+ */
+ public static void merge(final TransactionalEditingDomain domain, final DiffElement element, boolean leftToRight) {
+ final Command cmd = getMergeCommand(domain, element, leftToRight);
+ domain.getCommandStack().execute(cmd);
+ }
+
+ /**
+ * Execute the command to merge The DiffElement
+ *
+ * @param domain
+ * the {@link TransactionalEditingDomain}
+ * @param elements
+ * the elements to merge
+ * @param leftToRight
+ * <code>True</code> if the changes must be applied from the left to the right model, <code>False</code> when they have to be applied the
+ * other way around.
+ */
+ public static void merge(final TransactionalEditingDomain domain, final List<DiffElement> elements, final boolean leftToRight) {
+ final Command cmd = getMergeCommand(domain, elements, leftToRight);
+ domain.getCommandStack().execute(cmd);
+ }
+
+
+ public static Command getMergeCommand(final TransactionalEditingDomain domain, final List<DiffElement> elements, final boolean leftToRight) {
+ final CompoundCommand cmd = new CompoundCommand("MergeCommand"); //$NON-NLS-1$
+ cmd.append(new FireMergeOperationStartCommand(elements, getMergeListeners()));
+ for(DiffElement element : new ArrayList<DiffElement>(elements)) {
+ // we might remove the diff from the list before merging it
+ // (eOpposite reference)
+ if(element.eContainer() != null) {
+ cmd.append(getDoMergeCommand(domain, element, leftToRight));
+ }
+ }
+ cmd.append(new FireMergeOperationEndCommand(elements, getMergeListeners()));
+ return cmd;
+ }
+
+
+ // /**
+ // * removes a merge listener from the list of registered listeners. This will have no effect if the given
+ // * listener is not registered for notifications on this service.
+ // *
+ // * @param listener
+ // * New Listener to register for notifications.
+ // */
+ // public static void removeMergeListener(final IMergeListener listener) {
+ // if(removeMergeListenerMethod == null) {
+ // Class<?>[] parameterTypes = new Class[1];
+ // parameterTypes[0] = IMergeListener.class;
+ // try {
+ // removeMergeListenerMethod = ReflectHelper.getMethod(MergeService.class, "removeMergeListener", parameterTypes); //$NON-NLS-1$
+ // } catch (SecurityException e) {
+ // Activator.log.error(e);
+ // } catch (NoSuchMethodException e) {
+ // Activator.log.error(e);
+ // }
+ // }
+ // final Object[] parameters = new Object[1];
+ // parameters[0] = listener;
+ // try {
+ // removeMergeListenerMethod.invoke(null, parameters);
+ // } catch (IllegalArgumentException e) {
+ // Activator.log.error(e);
+ // } catch (IllegalAccessException e) {
+ // Activator.log.error(e);
+ // } catch (InvocationTargetException e) {
+ // Activator.log.error(e);
+ // }
+ // }
+
+
+ // @SuppressWarnings("unchecked")
+ // //we suppress this warning because the field is always a List of IMergeListener
+ // private static List<IMergeListener> getMergeListeners() {
+ // List<IMergeListener> listeners = null;
+ // Field myField = null;
+ // try {
+ // myField = MergeService.class.getDeclaredField("MERGE_LISTENERS"); //$NON-NLS-1$
+ // } catch (SecurityException e) {
+ // Activator.log.error(e);
+ // } catch (NoSuchFieldException e) {
+ // Activator.log.error(e);
+ // }
+ // myField.setAccessible(true);
+ // try {
+ // listeners = (List<IMergeListener>)myField.get(null);
+ // } catch (IllegalArgumentException e) {
+ // Activator.log.error(e);
+ // } catch (IllegalAccessException e) {
+ // Activator.log.error(e);
+ // }
+ // return listeners;
+ // }
+
+ private static List<IMergeListener> getMergeListeners() {
+ return MERGE_LISTENERS;
+ }
+
+
+ //FIXME : from HERE to the end : duplicated code from MergeService
+ /** This copier will be used when merging references. */
+ // private static EMFCompareEObjectCopier copier;
+
+ /**
+ * Holds a list of all the merge listeners registered for notifications on merge operations.
+ */
+ private static final List<IMergeListener> MERGE_LISTENERS = new ArrayList<IMergeListener>();
+
+
+ /**
+ * Registers a new merge listener for notifications about merge operations. Has no effect if the listener
+ * is already registered.
+ *
+ * @param listener
+ * New Listener to register for notifications.
+ */
+ //TODO should be done with a command...
+ public static void addMergeListener(IMergeListener listener) {
+ MERGE_LISTENERS.add(listener);
+ }
+
+ /**
+ * Returns the copier given the diff it should merge.
+ *
+ * @param diff
+ * The DiffElement for which a copier is needed.
+ * @return The copier for a given diff.
+ */
+ public static EMFCompareEObjectCopier getCopier(DiffElement diff) {
+ final DiffModel diffModel = getContainerDiffModel(diff);
+ if(diffModel == null)
+ throw new IllegalArgumentException("The diff element should be contained in a DiffModel instance"); //$NON-NLS-1$
+ if(diffModel.eContainer() instanceof DiffResourceSet) {
+ if(copier == null) {
+ copier = new PapyrusCompareEObjectCopier((DiffResourceSet)diffModel.eContainer());
+ } else if(copier.getDiffResourceSet() != diffModel.eContainer()) {
+ copier.clear();
+ copier = new PapyrusCompareEObjectCopier((DiffResourceSet)diffModel.eContainer());
+ }
+ } else {
+ if(copier == null) {
+ copier = new PapyrusCompareEObjectCopier(diffModel);
+ } else if(copier.getDiffModel() != diffModel) {
+ copier.clear();
+ copier = new PapyrusCompareEObjectCopier(diffModel);
+ }
+ }
+ return copier;
+ }
+
+ /**
+ * Browse the diff model from the leaf to the top to find the containing {@link DiffModel} instance.
+ *
+ * @param diff
+ * any {@link DiffElement}.
+ * @return the containing {@link DiffModel} instance, null if not found.
+ */
+ private static DiffModel getContainerDiffModel(DiffElement diff) {
+ EObject container = diff.eContainer();
+ while(container != null) {
+ if(container instanceof DiffModel)
+ return (DiffModel)container;
+ container = container.eContainer();
+ }
+ return null;
+ }
+
+ /**
+ * Merges a single DiffElement in the direction specified by <code>leftToRight</code>.
+ * <p>
+ * Will notify the list of its merge listeners before, and after the operation.
+ * </p>
+ *
+ * @param element
+ * {@link DiffElement} containing the information to merge.
+ * @param leftToRight
+ * <code>True</code> if the changes must be applied from the left to the right model, <code>False</code> when they have to be applied the
+ * other way around.
+ */
+ public static void merge(DiffElement element, boolean leftToRight) {
+ fireMergeOperationStart(element);
+ doMerge(element, leftToRight);
+ fireMergeOperationEnd(element);
+ }
+
+ /**
+ * Merges a list of DiffElements in the direction specified by <code>leftToRight</code>.
+ * <p>
+ * Will notify the list of its merge listeners before, and after the operation.
+ * </p>
+ *
+ * @param elements
+ * {@link DiffElement}s containing the information to merge.
+ * @param leftToRight
+ * <code>True</code> if the changes must be applied from the left to the right model, <code>False</code> when they have to be applied the
+ * other way around.
+ */
+ public static void merge(List<DiffElement> elements, boolean leftToRight) {
+ fireMergeOperationStart(elements);
+ for(DiffElement element : new ArrayList<DiffElement>(elements))
+ // we might remove the diff from the list before merging it
+ // (eOpposite reference)
+ if(element.eContainer() != null)
+ doMerge(element, leftToRight);
+ fireMergeOperationEnd(elements);
+ }
+
+ /**
+ * removes a merge listener from the list of registered listeners. This will have no effect if the given
+ * listener is not registered for notifications on this service.
+ *
+ * @param listener
+ * New Listener to register for notifications.
+ */
+ //TODO should be done with a command
+ public static void removeMergeListener(IMergeListener listener) {
+ MERGE_LISTENERS.remove(listener);
+ }
+
+ /**
+ * Applies the changes implied by a given {@link DiffElement} in the direction specified by <code>leftToRight</code>.
+ * <p>
+ * Will notify the list of its merge listeners before, and after the merge.
+ * </p>
+ *
+ * @param element
+ * {@link DiffElement} containing the information to merge.
+ * @param leftToRight
+ * <code>True</code> if the changes must be applied from the left to the right model, <code>False</code> when they have to be applied the
+ * other way around.
+ */
+ protected static void doMerge(DiffElement element, boolean leftToRight) {
+ fireMergeDiffStart(element);
+ final IMerger merger;
+ if(element instanceof ConflictingDiffElement)
+ merger = MergeFactory.createMerger(element.getSubDiffElements().get(0));
+ else
+ merger = MergeFactory.createMerger(element);
+ if(leftToRight && merger.canUndoInTarget()) {
+ merger.undoInTarget();
+ } else if(!leftToRight && merger.canApplyInOrigin()) {
+ merger.applyInOrigin();
+ }
+ fireMergeDiffEnd(element);
+ }
+
+ /**
+ * Notifies all registered listeners that a {@link DiffElement} has just been merged.
+ *
+ * @param diff
+ * {@link DiffElement} which has just been merged.
+ */
+ protected static void fireMergeDiffEnd(DiffElement diff) {
+ for(IMergeListener listener : MERGE_LISTENERS)
+ listener.mergeDiffEnd(new MergeEvent(diff));
+ }
+
+ /**
+ * Notifies all registered listeners that a DiffElement is about to be merged.
+ *
+ * @param diff
+ * {@link DiffElement} which is about to be merged.
+ */
+ protected static void fireMergeDiffStart(DiffElement diff) {
+ for(IMergeListener listener : MERGE_LISTENERS)
+ listener.mergeDiffStart(new MergeEvent(diff));
+ }
+
+ /**
+ * Notifies all registered listeners that a merge operation on a single diff just ended.
+ *
+ * @param diff
+ * {@link DiffElement} which has just been merged.
+ */
+ protected static void fireMergeOperationEnd(DiffElement diff) {
+ for(IMergeListener listener : MERGE_LISTENERS)
+ listener.mergeOperationEnd(new MergeEvent(diff));
+ }
+
+ /**
+ * Notifies all registered listeners that a merge operation has ended for a list of differences.
+ *
+ * @param diffs
+ * {@link DiffElement}s which have been merged.
+ */
+ protected static void fireMergeOperationEnd(List<DiffElement> diffs) {
+ for(IMergeListener listener : MERGE_LISTENERS)
+ listener.mergeOperationEnd(new MergeEvent(diffs));
+ }
+
+ /**
+ * Notifies all registered listeners that a merge operation is about to start for a single diff.
+ *
+ * @param diff
+ * {@link DiffElement} which is about to be merged.
+ */
+ protected static void fireMergeOperationStart(DiffElement diff) {
+ for(IMergeListener listener : MERGE_LISTENERS)
+ listener.mergeOperationStart(new MergeEvent(diff));
+ }
+
+ /**
+ * Notifies all registered listeners that a merge operation is about to start for a list of differences.
+ *
+ * @param diffs
+ * {@link DiffElement}s which are about to be merged.
+ */
+ protected static void fireMergeOperationStart(List<DiffElement> diffs) {
+ for(IMergeListener listener : MERGE_LISTENERS)
+ listener.mergeOperationStart(new MergeEvent(diffs));
+ }
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptions.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptions.java
new file mode 100644
index 00000000000..fcbb24040c8
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptions.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.utils;
+
+/**
+ *
+ * This class provides the keys for options managed by Papyrus Compare
+ *
+ */
+public class PapyrusCompareOptions {
+
+ private PapyrusCompareOptions() {
+ //to prevent instanciation
+ }
+
+ /**
+ * the keys to define the merge from left to right is enabled or not
+ */
+ public static final String KEY_ALLOW_MERGE_LEFT_TO_RIGHT = "allow_merge_left_to_right"; //$NON-NLS-1$
+
+ public static final String KEY_ALLOW_UNDO_IN_TARGET = KEY_ALLOW_MERGE_LEFT_TO_RIGHT;
+
+ /**
+ * the keys to define the merge from right to left is enabled or not
+ */
+ public static final String KEY_ALLOW_MERGE_RIGHT_TO_LEFT = "allow_merge_right_to_left"; //$NON-NLS-1$
+
+ public static final String KEY_ALLOW_APPLY_IN_ORIGIN = KEY_ALLOW_MERGE_RIGHT_TO_LEFT;
+
+ /**
+ * this key allows to ignore all changes on features
+ * the value associated to this key must be a list of EStructuralFeature to ignore
+ */
+ public static final String KEY_IGNORE_ALL_CHANGES_ON_FEATURES = "ignore_all_changes_on_features";
+
+ /**
+ * this key allows to define features changes to ignore for some elements
+ * the value linked to this key should be a Map<EStructuralFeature, List<EObject>>
+ */
+ public static final String KEY_IGNORE_CHANGES_ON_FEATURES_FOR = "ignore_changes_on_features_for";
+
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptionsUtils.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptionsUtils.java
new file mode 100644
index 00000000000..f54cc7005b1
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusCompareOptionsUtils.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.utils;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+
+/**
+ *
+ * Utils class for Papyrus Compare Options
+ *
+ */
+public class PapyrusCompareOptionsUtils {
+
+ private PapyrusCompareOptionsUtils() {
+ //to prevent instanciation
+ }
+
+ /**
+ *
+ * @param el
+ * a DiffElement
+ * @return
+ * the PapyrusCompareOptions instances attached to the DiffElement if it exists, or <code>null</code> if not found
+ */
+ public static final PapyrusOptionsAdapter getPapyrusOptionsAdapter(final DiffElement el) {
+ for(final Adapter current : el.eAdapters()) {
+ if(current instanceof PapyrusOptionsAdapter) {
+ return (PapyrusOptionsAdapter)current;
+ }
+ }
+ return null;
+ }
+}
diff --git a/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusOptionsAdapter.java b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusOptionsAdapter.java
new file mode 100644
index 00000000000..b5d389f1798
--- /dev/null
+++ b/deprecated/uml-compare-1.X/org.eclipse.papyrus.infra.emf.compare.diff/src/org/eclipse/papyrus/infra/emf/compare/diff/utils/PapyrusOptionsAdapter.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.compare.diff.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+
+/**
+ *
+ * This class is used to "add" options to DiffElement for the merge action
+ *
+ */
+public class PapyrusOptionsAdapter extends AdapterImpl {
+
+ /**
+ * the options used for the comparison
+ */
+ final private Map<String, Object> options;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param options
+ * the options used for the comparison
+ */
+ public PapyrusOptionsAdapter(final Map<String, Object> options) {
+ this.options = options;
+ }
+
+ /**
+ *
+ */
+ public PapyrusOptionsAdapter() {
+ this.options = new HashMap<String, Object>();
+ }
+
+ /**
+ *
+ * @return
+ * true if the registered options allows to apply the diff in origin (right to left)
+ */
+ public boolean canApplyInOrigin() {
+ final Boolean value = (Boolean)this.options.get(PapyrusCompareOptions.KEY_ALLOW_APPLY_IN_ORIGIN);
+ if(value == null) {
+ return true;
+ }
+ return value.booleanValue();
+ }
+
+ /**
+ *
+ * @return
+ * true if the registered options allows to undo the diff in target (left to right)
+ */
+ public boolean canUndoInTarget() {
+ final Boolean value = (Boolean)this.options.get(PapyrusCompareOptions.KEY_ALLOW_UNDO_IN_TARGET);
+ if(value == null) {
+ return true;
+ }
+ return value.booleanValue();
+ }
+
+ /**
+ * @see #canApplyInOrigin()
+ *
+ */
+ public boolean canMergeRightToLeft() {
+ return canApplyInOrigin();
+ }
+
+ /**
+ *
+ * @see #canUndoInTarget()
+ */
+ public boolean canMergeLeftToRight() {
+ return canUndoInTarget();
+ }
+
+}

Back to the top