Fix for deadlock when DnD an attribute between two entities when a Diagram with either Entity is open.

Change-Id: I9130965c845dcdbe6e47824c474dc2017aeb50d4
diff --git a/plugins/org.eclipse.tigerstripe.workbench.ui.base/src/java/org/eclipse/tigerstripe/workbench/ui/internal/views/explorerview/ArtifactComponentTransferDropAdapter.java b/plugins/org.eclipse.tigerstripe.workbench.ui.base/src/java/org/eclipse/tigerstripe/workbench/ui/internal/views/explorerview/ArtifactComponentTransferDropAdapter.java
index eebc5ee..a2bf28a 100644
--- a/plugins/org.eclipse.tigerstripe.workbench.ui.base/src/java/org/eclipse/tigerstripe/workbench/ui/internal/views/explorerview/ArtifactComponentTransferDropAdapter.java
+++ b/plugins/org.eclipse.tigerstripe.workbench.ui.base/src/java/org/eclipse/tigerstripe/workbench/ui/internal/views/explorerview/ArtifactComponentTransferDropAdapter.java
@@ -13,6 +13,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -22,9 +23,14 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.MultiRule;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.JavaModelException;
@@ -359,31 +365,28 @@
 						
 						
                     }
-
-                    ((IAbstractArtifactInternal) targetArtifact).doSave(new NullProgressMonitor());
-                    IResource res = ((IAbstractArtifactInternal) targetArtifact)
-                            .getAdapter(IResource.class);
-                    if (res != null) {
+                    Job saveArtifactsJob = Job.create("Saving artifacts", monitor -> {
+                        SubMonitor subMonitor = SubMonitor.convert(monitor, srcArtifacts.size() + 1);
                         try {
-                            res.refreshLocal(IResource.DEPTH_ZERO,
-                                    new NullProgressMonitor());
-                        } catch (CoreException e) {
-                            throw new TigerstripeException(e.getMessage(), e);
+                            saveAndRefresh((IAbstractArtifactInternal) targetArtifact, subMonitor.split(1));
+                        } catch (TigerstripeException e) {
+                            Status error = new Status(IStatus.ERROR, EclipsePlugin.getPluginId(), 222,
+                                    "Exception during model component move: " + e.getMessage(), e);
+                            EclipsePlugin.log(error);
                         }
-                    }
-                    for (IAbstractArtifact art : srcArtifacts.values()) {
-                        ((IAbstractArtifactInternal) art).doSave(new NullProgressMonitor());
-                        res = ((IAbstractArtifactInternal) art).getAdapter(IResource.class);
-                        if (res != null) {
+                        for (IAbstractArtifact art : srcArtifacts.values()) {
                             try {
-                                res.refreshLocal(IResource.DEPTH_ZERO,
-                                        new NullProgressMonitor());
-                            } catch (CoreException e) {
-                                throw new TigerstripeException(e.getMessage(),
-                                        e);
+                                saveAndRefresh((IAbstractArtifactInternal) art, subMonitor.split(1));
+                            } catch (TigerstripeException e) {
+                                Status error = new Status(IStatus.ERROR, EclipsePlugin.getPluginId(), 222,
+                                        "Exception during model component move: " + e.getMessage(), e);
+                                EclipsePlugin.log(error);
                             }
                         }
-                    }
+                    });
+                    saveArtifactsJob.setUser(true);
+                    saveArtifactsJob.setRule(getRuleForArtifacts(targetArtifact, srcArtifacts.values()));
+                    saveArtifactsJob.schedule();
                 } catch (TigerstripeException e) {
                     Status error = new Status(IStatus.ERROR, EclipsePlugin
                             .getPluginId(), 222,
@@ -397,6 +400,28 @@
             }
         });
     }
+    
+    private void saveAndRefresh(IAbstractArtifactInternal artifact, IProgressMonitor monitor) throws TigerstripeException {
+        SubMonitor subMonitor = SubMonitor.convert(monitor, "Saving artifact " + artifact.getName(), 2);
+        artifact.doSave(subMonitor.split(1));
+        IResource res = artifact.getAdapter(IResource.class);
+        if (res != null) {
+            try {
+                res.refreshLocal(IResource.DEPTH_ZERO, subMonitor.split(1));
+            } catch (CoreException e) {
+                throw new TigerstripeException(e.getMessage(), e);
+            }
+        }
+    }
+    
+    private ISchedulingRule getRuleForArtifacts(IAbstractArtifact targetArtifact, Collection<IAbstractArtifact> srcArtifacts) {
+        Collection<ISchedulingRule> schedulingRules = new ArrayList<>();
+        schedulingRules.add(((IAbstractArtifactInternal)targetArtifact).getAdapter(IResource.class));
+        for (IAbstractArtifact artifact : srcArtifacts) {
+            schedulingRules.add(((IAbstractArtifactInternal)artifact).getAdapter(IResource.class));
+        }
+        return new MultiRule(schedulingRules.toArray(new ISchedulingRule[schedulingRules.size()]));
+    }
 
     @Override
     public boolean validateDrop(Object target, int operation,