From ba82b7bce2619be6ea47db8b1d642f7433fa1eb1 Mon Sep 17 00:00:00 2001
From: Alexander Diewald <diewald@fortiss.org>
Date: Tue, 10 Jan 2017 16:48:00 +0000
Subject: [PATCH] - Correct the paste logic for N-ary EReference annotations. -
 Check each pasted referenced element if it can be pasted to the target
 annotation. refs 2361

---
 .../valueprovider/ValueProviderBase.java      | 42 +++++++++++++------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/org.fortiss.tooling.base/trunk/src/org/fortiss/tooling/base/annotation/valueprovider/ValueProviderBase.java b/org.fortiss.tooling.base/trunk/src/org/fortiss/tooling/base/annotation/valueprovider/ValueProviderBase.java
index 095933cd6..79a97dac6 100644
--- a/org.fortiss.tooling.base/trunk/src/org/fortiss/tooling/base/annotation/valueprovider/ValueProviderBase.java
+++ b/org.fortiss.tooling.base/trunk/src/org/fortiss/tooling/base/annotation/valueprovider/ValueProviderBase.java
@@ -28,6 +28,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.BiConsumer;
 
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EEnum;
 import org.eclipse.emf.ecore.EFactory;
@@ -47,7 +49,7 @@ import org.fortiss.tooling.kernel.utils.LoggingUtils;
  * @author diewald, barner
  * @author $Author$
  * @version $Rev$
- * @ConQAT.Rating GREEN Hash: 92072FF28C0A6055490A33DB8F1A062B
+ * @ConQAT.Rating YELLOW Hash: B246F4378421410475FECB9585F5CE05
  */
 public abstract class ValueProviderBase<T extends IAnnotatedSpecification> implements
 		IAnnotationValueProvider<T> {
@@ -367,19 +369,8 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 							annEntry.getSpecificationValue(
 									copiedAnnInst.getAnnotatedSpecificationType(),
 									copiedAnnInst.getInstanceKey());
-					T pasteAnnotation = parameters.getAnnotation();
 
-					// Prevent pasting of copied References that may not be set due to restrictions
-					// in the target annotation.
-					if(copiedValue instanceof EReference) {
-						EStructuralFeatureDescriptor featurDescr =
-								getEStructuralFeatureDescriptor(instanceKey);
-						if(!featurDescr.isAvailableObject((EReference)copiedValue,
-								copiedAnnInst.getAnnotatedSpecification(),
-								annEntry.getModelElement())) {
-							return;
-						}
-					}
+					T pasteAnnotation = parameters.getAnnotation();
 
 					if(pasteAnnotation != null) {
 						try {
@@ -426,6 +417,17 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 	@SuppressWarnings({"unchecked", "rawtypes"})
 	private void pasteValue(String instanceKey, boolean isManyRef, boolean doReplace,
 			Object copiedValue, T pasteAnnotation) throws Exception {
+		if(isManyRef) {
+			// Do not copy values that cannot be pasted the target
+			EList<EObject> castedList = new BasicEList((EList<EObject>)copiedValue);
+			castedList.removeIf(r -> !canPaste(r, instanceKey, pasteAnnotation));
+			copiedValue = castedList;
+		} else if(copiedValue instanceof EReference) {
+			if(!canPaste((EReference)copiedValue, instanceKey, pasteAnnotation)) {
+				return;
+			}
+		}
+
 		if(!isManyRef || doReplace) {
 			setAnnotationValue(copiedValue, pasteAnnotation);
 		} else {
@@ -435,4 +437,18 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 			setAnnotationValue(appendList, pasteAnnotation);
 		}
 	}
+
+	/**
+	 * Check whether the given {@link EObject} can be pasted to the target annotation. Used to
+	 * prevent pasting of copied References that may not be set due to restrictions in the target
+	 * annotation.
+	 */
+	private boolean canPaste(EObject refObj, String instanceKey, T pasteAnnotation) {
+		EStructuralFeatureDescriptor featurDescr = getEStructuralFeatureDescriptor(instanceKey);
+		if(featurDescr.isAvailableObject(refObj, pasteAnnotation,
+				pasteAnnotation.getSpecificationOf())) {
+			return true;
+		}
+		return false;
+	}
 }
-- 
GitLab