From ae1c6476f69c7a969763873309f60f29fd536eb4 Mon Sep 17 00:00:00 2001
From: Johannes Eder <eder@fortiss.org>
Date: Mon, 9 Dec 2019 14:35:36 +0100
Subject: [PATCH] remove unknown features after migrations

* if there are unknown features after migration, those ecore elements
will be removed

Issue-Ref: 3865
Issue-Url: https://af3-developer.fortiss.org/issues/3865

Signed-off-by: Johannes Eder <eder@fortiss.org>
---
 .../kernel/extension/IMigrationProvider.java  |  6 ++---
 .../fortiss/tooling/kernel/internal/.ratings  |  2 +-
 .../kernel/internal/MigrationService.java     | 22 ++++++++++++-------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java
index fdb1078df..cbf0d03c7 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java
@@ -49,8 +49,8 @@ public interface IMigrationProvider extends IObjectAware<ITopLevelElement> {
 	 * in the model. This can be useful to detect features coming from old models and can be then
 	 * translated to the new model by a migrator.
 	 * 
-	 * The migrator should remove from unknownFeatures the features that it dealt with.
-	 * If one forgets to do so, the migrator will run into an infinite loop!
+	 * @return all features which could not be migrated.
 	 */
-	void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures);
+	Map<EObject, AnyType> migrate(ITopLevelElement modelElement,
+			Map<EObject, AnyType> unknownFeatures);
 }
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings
index e6e117aec..cb265f465 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings
@@ -7,7 +7,7 @@ ElementCompositorService.java 98c5d27e09881e60aa4f87c1ac0c7787cdec9f7c GREEN
 LibraryPrototypeProvider.java b77eddbdca78f561ffb1233e98817be361c690ae GREEN
 LibraryService.java d22671ba820466062852c15873698adf28960d94 GREEN
 LoggingService.java da784259f7b456b54bf75c41ec268f64919ce78d GREEN
-MigrationService.java 632c13563a3d69681e2a608023fcdadbe5340c4b GREEN
+MigrationService.java f968fcb7de02f78e7d43c0654e958611296539d0 YELLOW
 PersistencyService.java 103eef642c038ef63fa49b743d803aaa3fea2724 GREEN
 PrototypeService.java 18c3db05ab11f189a9711bf241c3c7f35c954a9e GREEN
 ToolingKernelInternal.java d624a5f6b237ce993e150e2b8d1b4390e3fc8f7a GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java
index 632c13563..f968fcb7d 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java
@@ -20,6 +20,7 @@ import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstChildWithType;
 import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -27,6 +28,7 @@ import java.util.Map.Entry;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.emf.common.util.BasicEList;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
 import org.eclipse.emf.ecore.util.FeatureMap;
 import org.eclipse.emf.ecore.xml.type.AnyType;
 import org.fortiss.tooling.kernel.ToolingKernelActivator;
@@ -117,25 +119,29 @@ public class MigrationService extends ObjectAwareServiceBase<IMigrationProvider>
 
 			@Override
 			public void run() {
+				Map<EObject, AnyType> featuresNotMigrated = new HashMap<EObject, AnyType>();
 				for(IMigrationProvider provider : getProviders(input)) {
 					if(provider.needMigration(input, unknownFeatures)) {
-						provider.migrate(input, unknownFeatures);
+						featuresNotMigrated.putAll(provider.migrate(input, unknownFeatures));
 					}
 				}
-				if(!unknownFeatures.isEmpty()) {
-					error(ToolingKernelActivator.getDefault(),
-							input.getSaveableName() + " contains one or more unknown feature(s): " +
-									featuresToStrings(unknownFeatures));
-				}
-
 				for(IMigrationProvider provider : getProviders(input)) {
-					if(provider.needMigration(input, unknownFeatures)) {
+					if(provider.needMigration(input, featuresNotMigrated)) {
 						error(ToolingKernelActivator.getDefault(),
 								"Migrating " + input.getSaveableName() + " failed: A need for " +
 										"migration is indicated although the migration was " +
 										"already performed. Please fix the migrator (or model).");
 					}
 				}
+				if(!featuresNotMigrated.isEmpty()) {
+					error(ToolingKernelActivator.getDefault(), input.getSaveableName() +
+							" contains one or more unknown feature(s) which will be deleted: " +
+							featuresToStrings(unknownFeatures));
+
+					for(Entry<EObject, AnyType> e : featuresNotMigrated.entrySet()) {
+						EcoreUtil.delete(e.getKey(), true);
+					}
+				}
 			}
 		});
 
-- 
GitLab