From b7485bcdeca40a7ff8e97d9d001713565bcd7bf6 Mon Sep 17 00:00:00 2001
From: Christian W. Damus
Date: Wed, 28 Sep 2016 11:40:12 -0400
Subject: Bug 502461: [Copy/Paste] Pasting UML-RT protocol container corrupts
the model https://bugs.eclipse.org/bugs/show_bug.cgi?id=502461
Never copy the Dependency::client reference property of an
InterfaceRealization in copy/paste operations.
Use the Element Types Framework to set the name of a pasted element
when resolving name clashes, to allow for extensible editing
behaviour of DSMLs such as UML-RT (for protocol containers).
Change-Id: Iddfc4f7f4d5a9a412317f7fbe5db6a6ac7563be7
---
.../META-INF/MANIFEST.MF | 3 +-
.../core/org.eclipse.papyrus.infra.core/pom.xml | 2 +-
.../core/internal/clipboard/CopierFactory.java | 127 +++++++++++++++++++++
.../common/commands/DefaultCopyCommand.java | 8 +-
.../common/commands/DefaultPasteCommand.java | 6 +-
.../META-INF/MANIFEST.MF | 2 +-
.../tools/org.eclipse.papyrus.uml.tools/pom.xml | 2 +-
.../org/eclipse/papyrus/uml/tools/Activator.java | 42 ++++---
.../uml/tools/commands/RenameElementCommand.java | 46 +++++++-
9 files changed, 212 insertions(+), 26 deletions(-)
create mode 100644 plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/internal/clipboard/CopierFactory.java
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF b/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF
index eec2ac0e47a..ed09aea07e3 100644
--- a/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/META-INF/MANIFEST.MF
@@ -3,6 +3,7 @@ Export-Package: org.eclipse.papyrus.infra.core,
org.eclipse.papyrus.infra.core.clipboard,
org.eclipse.papyrus.infra.core.editor,
org.eclipse.papyrus.infra.core.extension,
+ org.eclipse.papyrus.infra.core.internal.clipboard;x-internal:=true,
org.eclipse.papyrus.infra.core.internal.expressions;x-internal:=true,
org.eclipse.papyrus.infra.core.internal.language;x-friends:="org.eclipse.papyrus.infra.emf",
org.eclipse.papyrus.infra.core.internal.sashmodel;x-internal:=true,
@@ -29,7 +30,7 @@ Require-Bundle: org.eclipse.emf.workspace;bundle-version="[1.5.0,2.0.0)",
org.eclipse.core.resources;bundle-version="[3.11.0,4.0.0)";visibility:=reexport
Bundle-Vendor: %providerName
Bundle-ActivationPolicy: lazy
-Bundle-Version: 2.1.0.qualifier
+Bundle-Version: 2.1.1.qualifier
Bundle-Name: %pluginName
Bundle-Localization: plugin
Bundle-Activator: org.eclipse.papyrus.infra.core.Activator
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/pom.xml b/plugins/infra/core/org.eclipse.papyrus.infra.core/pom.xml
index 7451b14b5f9..26e9fcc3e85 100644
--- a/plugins/infra/core/org.eclipse.papyrus.infra.core/pom.xml
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/pom.xml
@@ -7,6 +7,6 @@
0.0.1-SNAPSHOT
org.eclipse.papyrus.infra.core
- 2.1.0-SNAPSHOT
+ 2.1.1-SNAPSHOT
eclipse-plugin
\ No newline at end of file
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/internal/clipboard/CopierFactory.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/internal/clipboard/CopierFactory.java
new file mode 100644
index 00000000000..0bbf74a1c73
--- /dev/null
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/internal/clipboard/CopierFactory.java
@@ -0,0 +1,127 @@
+/*****************************************************************************
+ * Copyright (c) 2016 Christian W. Damus and others.
+ *
+ * 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:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.core.internal.clipboard;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.BiPredicate;
+import java.util.function.Supplier;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
+
+/**
+ * A factory that creates copiers for the Papyrus Clipboard.
+ */
+public class CopierFactory implements Supplier {
+
+ private static List> referenceFilters = new CopyOnWriteArrayList<>();
+
+ private final boolean useOriginalReferences;
+
+ /**
+ * The default copier factory that provides the usual EMF
+ * copying semantics, except with filtering of references
+ * as directed by {@linkplain #registerReferenceFilter(BiPredicate) registered filters}.
+ */
+ public static CopierFactory DEFAULT = new CopierFactory(true);
+
+ /**
+ * Initializes me.
+ *
+ * @param useOriginalReferences
+ * whether non-copied references should be used while copying
+ */
+ public CopierFactory(boolean useOriginalReferences) {
+ super();
+
+ this.useOriginalReferences = useOriginalReferences;
+ }
+
+ /**
+ * Queries whether non-copied references should be used while copying.
+ *
+ * @return whether to use non-copied references
+ */
+ public boolean isUseOriginalReferences() {
+ return useOriginalReferences;
+ }
+
+ @Override
+ public Copier get() {
+ Copier result;
+
+ Optional> referenceFilter = getReferenceFilter();
+ result = referenceFilter.map(this::createReferenceFilteringCopier)
+ .orElseGet(this::createBasicCopier);
+
+ return result;
+ }
+
+ /**
+ * Obtains a predicate that accepts any reference not matching
+ * any of our registered filters (a {@code not} of the collective
+ * {@code or} of our filters).
+ *
+ * @return the optional reference filter
+ */
+ private Optional> getReferenceFilter() {
+ return referenceFilters.stream()
+ .reduce(BiPredicate::or)
+ .map(BiPredicate::negate);
+ }
+
+ private Copier createReferenceFilteringCopier(BiPredicate super EReference, ? super EObject> referencePredicate) {
+ return new ReferenceFilteringCopier(true, isUseOriginalReferences(), referencePredicate);
+ }
+
+ private Copier createBasicCopier() {
+ return new Copier(true, isUseOriginalReferences());
+ }
+
+ /**
+ * Registers a predicate that matches references to be excluded from copy operations.
+ *
+ * @param filter
+ * a predicate that matches a reference to be excluded for a given owner object
+ */
+ public static void registerReferenceFilter(BiPredicate super EReference, ? super EObject> filter) {
+ referenceFilters.add(filter);
+ }
+
+ //
+ // Nested types
+ //
+
+ private static class ReferenceFilteringCopier extends Copier {
+ private static final long serialVersionUID = 1L;
+
+ private final BiPredicate super EReference, ? super EObject> referencePredicate;
+
+ ReferenceFilteringCopier(boolean resolveReferences, boolean useOriginalReferences, BiPredicate super EReference, ? super EObject> referencePredicate) {
+ super(resolveReferences, useOriginalReferences);
+
+ this.referencePredicate = referencePredicate;
+ }
+
+ @Override
+ protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) {
+ if (referencePredicate.test(eReference, eObject)) {
+ super.copyReference(eReference, eObject, copyEObject);
+ }
+ }
+ }
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DefaultCopyCommand.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DefaultCopyCommand.java
index 6703095a1a1..7c7abf28f38 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DefaultCopyCommand.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DefaultCopyCommand.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 CEA LIST.
+ * Copyright (c) 2014, 2016 CEA LIST, Christian W. Damus, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,7 @@
*
* Contributors:
* Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - Initial API and implementation
+ * Christian W. Damus - bug 502461
*****************************************************************************/
package org.eclipse.papyrus.infra.gmfdiag.common.commands;
@@ -20,6 +21,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AbstractOverrideableCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.papyrus.infra.core.clipboard.PapyrusClipboard;
+import org.eclipse.papyrus.infra.core.internal.clipboard.CopierFactory;
import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
import org.eclipse.papyrus.infra.gmfdiag.common.preferences.PastePreferencesPage;
@@ -47,8 +49,8 @@ public class DefaultCopyCommand extends AbstractOverrideableCommand implements N
public DefaultCopyCommand(EditingDomain domain, PapyrusClipboard papyrusClipboard, Collection pObjectsToPutInClipboard) {
super(domain);
objectsToPutInClipboard = new ArrayList