Improve performance of DiagramMigrationHook

The DiagramMigrationHook is inefficient for creating transactional
editing domains, which is very costly as these domains install adapters
to each object. The DiagramMigrationHook now creates a new transactional
editing domain for each diagram and disposes it again.

Instead the editing domain should only be created if needed and be
reused across migrating all diagrams.

Change-Id: I3abda32c4248e853c6568cd47f2ba3b3a0e6a161
Signed-off-by: Philip Langer <planger@eclipsesource.com>
diff --git a/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java b/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java
index fce3f7d..90b4232 100644
--- a/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java
+++ b/compare/bundles/org.eclipse.papyrus.compare.diagram.ide.ui/src/org/eclipse/papyrus/compare/diagram/ide/ui/internal/DiagramMigrationHook.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016, 2017 Ericsson and others.
+ * Copyright (c) 2016, 2019 Ericsson 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
@@ -8,6 +8,7 @@
  * Contributors:
  *     Simon Delisle - initial API and implementation
  *     Christian W. Damus - bug 527638
+ *     Philip Langer - performance improvement
  *******************************************************************************/
 package org.eclipse.papyrus.compare.diagram.ide.ui.internal;
 
@@ -17,13 +18,13 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EReference;
@@ -37,6 +38,7 @@
 import org.eclipse.gmf.runtime.common.core.command.ICommand;
 import org.eclipse.gmf.runtime.notation.Diagram;
 import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.papyrus.infra.emf.edit.domain.PapyrusTransactionalEditingDomain;
 import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe;
 import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel;
 import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramReconciler;
@@ -58,22 +60,39 @@
 
 	@Override
 	public void postLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) {
+		List<Diagram> diagramsNeedingMigration = getDiagramsNeedingMigration(resourceSet);
+		if (diagramsNeedingMigration.isEmpty()) {
+			return;
+		}
+
+		TransactionalEditingDomain domain = getEditingDomain(resourceSet);
+		try {
+			for (Diagram diagram : diagramsNeedingMigration) {
+				IDGenerator idgen = new IDGenerator(diagram);
+				try {
+					migrateDiagram(domain, diagram);
+				} finally {
+					idgen.dispose();
+				}
+			}
+		} finally {
+			domain.dispose();
+		}
+	}
+
+	private List<Diagram> getDiagramsNeedingMigration(ResourceSet resourceSet) {
+		List<Diagram> diagramsNeedingMigration = new ArrayList<>();
 		for (Resource resource : new ArrayList<Resource>(resourceSet.getResources())) {
 			if (NotationModel.NOTATION_FILE_EXTENSION.equals(resource.getURI().fileExtension())) {
-				EList<EObject> contents = resource.getContents();
-				for (EObject object : contents) {
-					if (object instanceof Diagram) {
-						Diagram diagram = (Diagram)object;
-						IDGenerator idgen = new IDGenerator(diagram);
-						try {
-							migrateDiagram(getEditingDomain(resourceSet), diagram);
-						} finally {
-							idgen.dispose();
-						}
+				for (EObject object : resource.getContents()) {
+					if (object instanceof Diagram
+							&& !DiagramVersioningUtils.isOfCurrentPapyrusVersion((Diagram)object)) {
+						diagramsNeedingMigration.add((Diagram)object);
 					}
 				}
 			}
 		}
+		return diagramsNeedingMigration;
 	}
 
 	/**
@@ -87,7 +106,7 @@
 		TransactionalEditingDomain existingDomain = TransactionalEditingDomain.Factory.INSTANCE
 				.getEditingDomain(resourceSet);
 		if (existingDomain == null) {
-			return TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(resourceSet);
+			return PapyrusTransactionalEditingDomain.FACTORY.createEditingDomain(resourceSet);
 		} else {
 			return existingDomain;
 		}
@@ -103,45 +122,43 @@
 	private CompositeCommand buildCommand(Diagram diagram) {
 		CompositeCommand reconcileCommand = null;
 
-		if (!DiagramVersioningUtils.isOfCurrentPapyrusVersion(diagram)) {
-			reconcileCommand = new CompositeCommand("Reconciling"); //$NON-NLS-1$
+		reconcileCommand = new CompositeCommand("Reconciling"); //$NON-NLS-1$
 
-			String sourceVersion = DiagramVersioningUtils.getCompatibilityVersion(diagram);
-			Map<String, Collection<DiagramReconciler>> diagramReconcilers = DiagramReconcilersReader
-					.getInstance().load();
-			String diagramType = diagram.getType();
-			Collection<DiagramReconciler> reconcilers = new LinkedList<DiagramReconciler>();
-			if (diagramReconcilers.containsKey(diagramType)) {
-				reconcilers.addAll(diagramReconcilers.get(diagramType));
+		String sourceVersion = DiagramVersioningUtils.getCompatibilityVersion(diagram);
+		Map<String, Collection<DiagramReconciler>> diagramReconcilers = DiagramReconcilersReader.getInstance()
+				.load();
+		String diagramType = diagram.getType();
+		Collection<DiagramReconciler> reconcilers = new LinkedList<DiagramReconciler>();
+		if (diagramReconcilers.containsKey(diagramType)) {
+			reconcilers.addAll(diagramReconcilers.get(diagramType));
+		}
+
+		boolean someFailed = false;
+		Iterator<DiagramReconciler> reconciler = reconcilers.iterator();
+		while (reconciler.hasNext() && !someFailed) {
+			DiagramReconciler next = reconciler.next();
+
+			if (!next.canReconcileFrom(diagram, sourceVersion)) {
+				// asked for ignore it for this instance, all fine
+				continue;
+			}
+			ICommand nextCommand = next.getReconcileCommand(diagram);
+			if (nextCommand == null) {
+				// legitimate no-op response, all fine
+				continue;
 			}
 
-			boolean someFailed = false;
-			Iterator<DiagramReconciler> reconciler = reconcilers.iterator();
-			while (reconciler.hasNext() && !someFailed) {
-				DiagramReconciler next = reconciler.next();
-
-				if (!next.canReconcileFrom(diagram, sourceVersion)) {
-					// asked for ignore it for this instance, all fine
-					continue;
-				}
-				ICommand nextCommand = next.getReconcileCommand(diagram);
-				if (nextCommand == null) {
-					// legitimate no-op response, all fine
-					continue;
-				}
-
-				if (nextCommand.canExecute()) {
-					reconcileCommand.add(nextCommand);
-				} else {
-					CompareDiagramIDEUIPapyrusPlugin.getDefault().getLog().log(new Status(IStatus.ERROR,
-							CompareDiagramIDEUIPapyrusPlugin.PLUGIN_ID,
-							"Diagram reconciler " + next + " failed to reconcile diagram: " + diagram)); //$NON-NLS-1$ //$NON-NLS-2$
-					someFailed = true;
-				}
+			if (nextCommand.canExecute()) {
+				reconcileCommand.add(nextCommand);
+			} else {
+				CompareDiagramIDEUIPapyrusPlugin.getDefault().getLog()
+						.log(new Status(IStatus.ERROR, CompareDiagramIDEUIPapyrusPlugin.PLUGIN_ID,
+								"Diagram reconciler " + next + " failed to reconcile diagram: " + diagram)); //$NON-NLS-1$ //$NON-NLS-2$
+				someFailed = true;
 			}
-			if (someFailed) {
-				reconcileCommand = null;
-			}
+		}
+		if (someFailed) {
+			reconcileCommand = null;
 		}
 		return reconcileCommand;
 	}
@@ -157,7 +174,6 @@
 	private void migrateDiagram(TransactionalEditingDomain domain, Diagram diagram) {
 		CompositeCommand migrationCommand = buildCommand(diagram);
 		if (migrationCommand == null) {
-			domain.dispose();
 			return;
 		}
 
@@ -169,8 +185,6 @@
 			GMFUnsafe.write(domain, migrationCommand);
 		} catch (Exception e) {
 			logException(e);
-		} finally {
-			domain.dispose();
 		}
 	}