[546681] Fix NPEs when closing editors asynchronously

Patch https://git.eclipse.org/r/c/125716 on the platform cleans up
some fields which asynchronous callbacks used to access for closing
the editors. At the time the callbacks are executed, getPage() and
getWorkbenchWindow() now return null.

For DDiagramEditorImpl, the solution is the same that was used in GMF
Runtime 1.12.1 itself, but it is reproduced here to avoid the bug when
running with previous versions of GMF.

For tables & trees, we rely on our own helpers as the context if
different and we do not have access to all the methods needed for the
GMF solution.

Bug: 546681
Change-Id: I9a7831ea2643c7f7b8090633f524e2c035406fc8
Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/editor/DDiagramEditorImpl.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/editor/DDiagramEditorImpl.java
index 2ade680..2d8c853 100644
--- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/editor/DDiagramEditorImpl.java
+++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/internal/editor/DDiagramEditorImpl.java
@@ -230,7 +230,9 @@
 import org.eclipse.ui.ISaveablePart2;
 import org.eclipse.ui.ISaveablesSource;
 import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.Saveable;
@@ -469,7 +471,31 @@
             getRepresentation().getUiState().getDecorationImage().clear();
         }
 
-        super.close(save);
+        // Prior to version 1.12.1 from 2019-06, GMF Runtime's close() is subject to NPEs when
+        // running the closeEditor asynchronously, so do not call super.close() directly but
+        // perform a slightly more robust version of the same code. This is the same code that
+        // was added in GMF Runtime 1.12.1, but we reproduce it here to still avoid the error when
+        // running with previous versions.
+        
+        enableSanityChecking(false);
+
+        Display display = Display.getCurrent();
+        if (display == null) {
+            display = PlatformUI.getWorkbench().getDisplay();
+        }
+        if (!display.isDisposed()) {
+            display.asyncExec(() -> {
+                if (getGraphicalViewer() != null && !PlatformUI.getWorkbench().isClosing()) {
+                    IWorkbenchPartSite site = getSite();
+                    if (site != null) {
+                        IWorkbenchPage page = site.getPage();
+                        if (page != null) {
+                            page.closeEditor(DDiagramEditorImpl.this, save);
+                        }
+                    }
+                }
+            });
+        }
     }
 
     /**
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/business/internal/dialect/TableDialectUIServices.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/business/internal/dialect/TableDialectUIServices.java
index 5d13cef..9cd8dca 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/business/internal/dialect/TableDialectUIServices.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/business/internal/dialect/TableDialectUIServices.java
@@ -79,7 +79,6 @@
 import org.eclipse.sirius.viewpoint.description.DescriptionPackage;
 import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
 import org.eclipse.sirius.viewpoint.description.RepresentationExtensionDescription;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IWorkbenchPage;
@@ -192,11 +191,10 @@
         if (editorPart instanceof AbstractDTableEditor) {
             // We launch the close in asyncExec to avoid the problem with the
             // WorkspaceSynchronizer
-            final Display display = editorPart.getSite().getShell().getDisplay();
-            display.asyncExec(new Runnable() {
-                @Override
-                public void run() {
-                    PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().closeEditor(editorPart, save);
+            EclipseUIUtil.displayAsyncExec(() -> {
+                IWorkbenchPage page = EclipseUIUtil.getActivePage();
+                if (page != null) {
+                    page.closeEditor(editorPart, save);
                 }
             });
         }
diff --git a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java
index 561b2c7..8d4ea7e 100644
--- a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java
+++ b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java
@@ -453,8 +453,8 @@
         if (pageRegistry != null) {
             pageRegistry.removeRegistryListener(this);
             pageRegistry = null;
+            super.close(save);
         }
-        super.close(save);
     }
 
     @Override