ref #9541 new referencing objects implementation in TaxEditor
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / AbstractUtility.java
index da95042cc0722a262c44401fb1527b6fdfd3db43..d88e763131b749ab982c4021ff1f276f8f59e715 100644 (file)
  * The contents of this file are subject to the Mozilla Public License Version 1.1
  * See LICENSE.TXT at the top of this package for the full license terms.
  */
-
 package eu.etaxonomy.taxeditor.model;
 
-import java.lang.reflect.InvocationTargetException;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.commands.NotEnabledException;
-import org.eclipse.core.commands.NotHandledException;
-import org.eclipse.core.commands.common.NotDefinedException;
 import org.eclipse.core.commands.operations.AbstractOperation;
 import org.eclipse.core.commands.operations.IOperationHistory;
 import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.ICoreRunnable;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.ui.di.UISynchronize;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.resource.ColorRegistry;
-import org.eclipse.jface.resource.FontRegistry;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
-import org.eclipse.ui.part.EditorPart;
 import org.eclipse.ui.progress.IProgressConstants;
-import org.eclipse.ui.progress.IProgressService;
-import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
-import org.eclipse.ui.themes.ITheme;
-import org.eclipse.ui.themes.IThemeManager;
 
 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
 import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
+import eu.etaxonomy.cdm.api.service.UpdateResult;
 import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
-import eu.etaxonomy.cdm.model.common.IEnumTerm;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.io.common.ExportDataWrapper;
+import eu.etaxonomy.cdm.io.common.ExportResult;
+import eu.etaxonomy.cdm.io.common.ExportResultType;
+import eu.etaxonomy.cdm.io.common.ExportType;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.taxon.Synonym;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
+import eu.etaxonomy.cdm.model.term.IEnumTerm;
+import eu.etaxonomy.taxeditor.event.EventUtility;
+import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
 import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
 import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
-import eu.etaxonomy.taxeditor.operation.RemotingCdmHandler;
+import eu.etaxonomy.taxeditor.operation.e4.CdmHandlerE4;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
 import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
-import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
-import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
-import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
-import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
+import eu.etaxonomy.taxeditor.view.e4.AbstractCdmDataViewerE4;
+import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
+import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
 
 /**
- *
  * @author n.hoffmann
  * @created 11.05.2009
- * @version 1.0
  */
 public abstract class AbstractUtility {
 
-    private static final Logger logger = Logger.getLogger(AbstractUtility.class);
+    protected static final Logger logger = Logger.getLogger(AbstractUtility.class);
 
     /** Constant <code>statusLineManager</code> */
     protected static IStatusLineManager statusLineManager;
+    /** Constant <code>DATE_FORMAT_NOW="yyyyMMddHHmm"</code> */
+       public static final String DATE_FORMAT_NOW = "yyyyMMddHHmm";
 
-
-    public static boolean closeAll() {
-        if(getActivePage()!=null){
-            return getActivePage().closeAllEditors(true);
-        }
-        return false;
-    }
-
-    /**
-     * Close the given editor.
-     *
-     * @param editor
-     *            The <tt>MultipageTaxonEditor</tt> to close.
-     * @return <tt>true</tt> on success
-     */
-    public static boolean close(EditorPart editor) {
-        return getActivePage() != null ? getActivePage().closeEditor(editor, true):false;
-    }
-
-    public static Shell getShell() {
-
-        return TaxeditorStorePlugin.getDefault().getWorkbench()
-                .getActiveWorkbenchWindow().getShell();
-    }
-
-    public static IWorkbenchPage getActivePage() {
-        try{
-            return TaxeditorStorePlugin.getDefault().getWorkbench()
-                    .getActiveWorkbenchWindow().getActivePage();
-        } catch(NullPointerException npe){
-            return null;
-        }
-    }
-
-    public static IWorkbenchPart getActiveWorkbenchPart() {
-        IWorkbenchPage activePage = getActivePage();
-        if(activePage!=null){
-            IWorkbenchPart activePart = activePage.getActivePart();
-            if(activePart!=null){
-                return activePart;
-            }
+    public static Object getActivePart() {
+        MPart activePart = EventUtility.getActivePart();
+        if(activePart!=null){
+            return activePart.getObject();
         }
         return null;
     }
 
-    public static Object getActiveE4Part() {
-        IWorkbenchPage activePage = getActivePage();
-        if(activePage!=null){
-            IWorkbenchPart activePart = activePage.getActivePart();
-            Object e4WrappedPart = WorkbenchUtility.getE4WrappedPart(activePart);
-            return e4WrappedPart!=null?e4WrappedPart:activePart;
-        }
-        return null;
+    public static Shell getShell() {
+        return EventUtility.getShell();
     }
 
     public static IWorkbench getWorkbench() {
         return TaxeditorStorePlugin.getDefault().getWorkbench();
     }
 
-    public static IWorkbenchWindow getWorkbenchWindow() {
-        if (getWorkbench().getWorkbenchWindowCount() > 1) {
-            throw new IllegalStateException("More than one workbench window");
-        }
-        return getWorkbench().getWorkbenchWindows()[0];
-    }
-
-    public static IViewPart showView(String id) {
-        try {
-            return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
-                    .getActivePage()
-                    .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
-        } catch (PartInitException e) {
-            MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
-            return null;
-        }
-    }
-
-    public static void hideView(IViewPart view) {
-        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
-        .hideView(view);
-    }
-
-    public static IViewPart getView(String id, boolean restore) {
-       IWorkbench workbench = PlatformUI.getWorkbench();
-        IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
-       IViewReference[] references = null;
-       if(activeWorkbenchWindow!=null && activeWorkbenchWindow.getActivePage()!=null){
-           references = activeWorkbenchWindow.getActivePage().getViewReferences();
-       }
-       else if(workbench.getWorkbenchWindows().length>0 && workbench.getWorkbenchWindows()[0].getActivePage()!=null){
-               references = workbench.getWorkbenchWindows()[0].getActivePage().getViewReferences();
-       }
-       if(references!=null){
-               for (IViewReference reference : references) {
-                       if (reference.getId().equals(id)) {
-                               return reference.getView(restore);
-                       }
-               }
-       }
-        return null;
-    }
-
+    @SuppressWarnings("unchecked")
     public static Object getService(Class api) {
         return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
     }
 
-    public static ITheme getCurrentTheme() {
-        IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
-                .getWorkbench().getThemeManager();
-        return themeManager.getCurrentTheme();
-    }
-
-    /**
-     * Fonts registered to the plugin may be obtained with the Eclipse themeing
-     * functionality. Thus fonts are chooseable by the user via
-     * Preferences->General->Appearance->Colors and Fonts
-     *
-     * @return the FontRegistry for the current theme
-     */
-    public static FontRegistry getFontRegistry() {
-        return getCurrentTheme().getFontRegistry();
-    }
-
     public static Font getFont(String symbolicName) {
-        return getFontRegistry().get(symbolicName);
-    }
-
-    /**
-     * Color registered to the plugin may be obtained with the Eclipse themeing
-     * functionality. Thus colors are editable by the user via
-     * Preferences->General->Appearance->Colors and Fonts
-     *
-     * @return the ColorRegistry for the current theme
-     */
-    public static ColorRegistry getColorRegistry() {
-        return getCurrentTheme().getColorRegistry();
+        return FontResources.getFont(symbolicName);
     }
 
     public static Color getColor(String symbolicName) {
-        return getColorRegistry().get(symbolicName);
+        return ColorResources.getColor(symbolicName);
     }
 
-    public static IStatus executeOperation(final AbstractPostOperation operation) {
+    public static IStatus executeOperation(final AbstractPostOperation operation, UISynchronize sync) {
         if (getOperationHistory() == null) {
             throw new IllegalArgumentException(
                     "There is no operation history for this context");
@@ -243,21 +136,17 @@ public abstract class AbstractUtility {
         final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
                 .getUIInfoAdapter(getShell());
 
-        IRunnableWithProgress runnable = new IRunnableWithProgress() {
-
-            @Override
-            public void run(IProgressMonitor monitor)
-                    throws InvocationTargetException, InterruptedException {
+        Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
+            sync.syncExec(() -> {
                 String operationlabel = operation.getLabel();
                 monitor.beginTask(operationlabel, 100);
                 IStatus status = Status.CANCEL_STATUS;
                 try {
                     operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
-                    status = getOperationHistory().execute(operation, monitor,
-                            uiInfoAdapter);
+                    status = operation.execute(monitor, uiInfoAdapter);
                 } catch (ExecutionException e) {
 
-                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+                    MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
 
                 } finally {
                     monitor.done();
@@ -266,25 +155,30 @@ public abstract class AbstractUtility {
                 String statusString = status.equals(Status.OK_STATUS) ? "completed"
                         : "cancelled";
                 setStatusLine(operationlabel + " " + statusString + ".");
-
-            }
-        };
+                IPostOperationEnabled postOperationEnabled = operation
+                        .getPostOperationEnabled();
+                if (postOperationEnabled != null) {
+                    postOperationEnabled.onComplete();
+                }
+            });
+        });
 
         try {
-            runInUI(runnable, null);
+            job.setUser(true);
+            job.schedule();
         } catch (Exception e) {
-            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occurred while executing " + operation.getLabel(), e);
         }
 
-        IPostOperationEnabled postOperationEnabled = operation
-                .getPostOperationEnabled();
-        if (postOperationEnabled != null) {
-            postOperationEnabled.onComplete();
-        }
         return Status.OK_STATUS;
     }
 
-    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
+    public static IStatus executeOperation(final AbstractOperation operation, final CdmHandlerE4 handler, UISynchronize sync) {
+        return executeOperation_internal(operation, handler, sync);
+    }
+
+    private static IStatus executeOperation_internal(final AbstractOperation operation, final CdmHandlerE4 handler,
+            UISynchronize sync) {
         if (getOperationHistory() == null) {
             throw new IllegalArgumentException(
                     "There is no operation history for this context");
@@ -293,23 +187,19 @@ public abstract class AbstractUtility {
         final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
                 .getUIInfoAdapter(getShell());
 
-        IRunnableWithProgress runnable = new IRunnableWithProgress() {
 
-            @Override
-            public void run(IProgressMonitor monitor)
-                    throws InvocationTargetException, InterruptedException {
+        Job job = Job.create(operation.getLabel(), (ICoreRunnable) monitor -> {
+            sync.syncExec(() -> {
                 String operationlabel = operation.getLabel();
                 monitor.beginTask(operationlabel, 100);
                 IStatus status = Status.CANCEL_STATUS;
                 try {
                     operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
-                    status = getOperationHistory().execute(operation, monitor,
+                    status = operation.execute(monitor,
                             uiInfoAdapter);
-                    if(handler != null) {
-                        handler.postOperation(status);
-                    }
+                    handler.postOperation(status);
                 } catch (ExecutionException e) {
-                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+                    MessagingUtils.operationDialog(AbstractUtility.class, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
                 } finally {
                     monitor.done();
                 }
@@ -317,14 +207,14 @@ public abstract class AbstractUtility {
                 String statusString = status.equals(Status.OK_STATUS) ? "completed"
                         : "cancelled";
                 setStatusLine(operationlabel + " " + statusString + ".");
-
-            }
-        };
+            });
+        });
 
         try {
-            runInUI(runnable, null);
+            job.setUser(true);
+            sync.syncExec(()->job.schedule());
         } catch (Exception e) {
-            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occurred while executing " + operation.getLabel(), e);
         }
 
         return Status.OK_STATUS;
@@ -340,12 +230,14 @@ public abstract class AbstractUtility {
      * @param postOp callback for running post operation logic
      * @return
      */
-    public static IStatus executeMoniteredOperation(final String label,
+    public static IStatus executeMoniteredExport(final String label,
             final UUID uuid,
             final int pollInterval,
             final boolean cancelable,
             final IPostMoniteredOperationEnabled postOp,
-            final IFeedbackGenerator feedbackGenerator) {
+            final IFeedbackGenerator feedbackGenerator,
+            String urlString,
+            boolean createZip) {
 
         try {
             // get the remoting monitor the first time to make sure that the
@@ -355,6 +247,9 @@ public abstract class AbstractUtility {
             if(firstRemotingMonitor == null) {
                 throw new IllegalStateException("Remoting progress monitor is null");
             }
+            if (firstRemotingMonitor.isDone()){
+                createExportResult(label, urlString, createZip, firstRemotingMonitor);
+            }
 
             Job job = new Job(label) {
 
@@ -362,6 +257,8 @@ public abstract class AbstractUtility {
                 @Override
                 public IStatus run(IProgressMonitor monitor) {
                     // run the monitor until the operation is finished
+                    SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
+                    //subMonitor.beginTask("Start", 100);
                     IRemotingProgressMonitor remotingMonitor;
                     try {
                         remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
@@ -369,30 +266,17 @@ public abstract class AbstractUtility {
                                 pollInterval,
                                 postOp,
                                 feedbackGenerator,
-                                monitor);
+                                subMonitor);
                     } catch (Exception ex) {
-                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
-                    }
-                    final StringBuilder reportSb = new StringBuilder();
-                    // collect reports
-                    for(String report : remotingMonitor.getReports()) {
-                        reportSb.append(report);
-                    }
-                    if(!StringUtils.isBlank(reportSb.toString())) {
-                        Display.getDefault().asyncExec(new Runnable() {
-                            @Override
-                            public void run() {
-                                // display reports with possibility to save
-                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
-                                dialog.setTitle(label + " Report");
-                                dialog.setReportText(reportSb.toString());
-                                dialog.open();
-                            }
-                        });
+                        return new Status(IStatus.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
                     }
+
+                    createExportResult(label, urlString, createZip, remotingMonitor);
                     return Status.OK_STATUS;
                 }
 
+
+
                 @Override
                 protected void canceling() {
                     CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
@@ -402,13 +286,14 @@ public abstract class AbstractUtility {
             // configure the job
             job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
             job.setUser(true);
+            job.setName(label);
             // schedule job
             job.schedule();
 
         } catch (Exception e) {
             MessagingUtils.errorDialog("Error executing operation",
                     AbstractUtility.class,
-                    "An error occured while executing " + label,
+                    "An error occurred while executing " + label,
                     TaxeditorStorePlugin.PLUGIN_ID,
                     e,
                     true);
@@ -506,85 +391,36 @@ public abstract class AbstractUtility {
         newMonitor.worked(steps);
     }
 
-    /**
-     * Present a progress dialog to the user. This dialog will block the UI
-     *
-     * @param runnable
-     *            an implementation of {@link IRunnableWithProgress}
-     * @throws java.lang.InterruptedException
-     *             if any.
-     * @throws java.lang.reflect.InvocationTargetException
-     *             if any.
-     */
-    public static void busyCursorWhile(IRunnableWithProgress runnable)
-            throws InvocationTargetException, InterruptedException {
-        getProgressService().busyCursorWhile(runnable);
-    }
-
-    public static void runInUI(IRunnableWithProgress runnable,
-            ISchedulingRule rule) throws InvocationTargetException,
-            InterruptedException {
-        getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
-    }
-
-    public static void run(boolean fork, boolean cancelable,
-            IRunnableWithProgress runnable) throws InvocationTargetException,
-            InterruptedException {
-        getProgressService().run(fork, cancelable, runnable);
-    }
-
-    public static IProgressService getProgressService() {
-        IWorkbench workbench = PlatformUI.getWorkbench();
-        return workbench.getProgressService();
-    }
-
-    public static IWorkbenchSiteProgressService getProgressService2() {
-        return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
-    }
-
     public static String getPluginId() {
         return "eu.taxeditor";
     }
 
-    public static IEditorPart getActiveEditor() {
-        return getActivePage() != null ? getActivePage().getActiveEditor()
-                : null;
-    }
-
-    public static Object getActiveE4Editor() {
-        if(getActivePage()!=null){
-            IEditorPart activeEditor = getActivePage().getActiveEditor();
-            Object wrappedPart = WorkbenchUtility.getE4WrappedPart(getActivePage().getActivePart());
-            return wrappedPart!=null?wrappedPart:activeEditor;
+    public static Object getActiveEditor() {
+        MPart activePart = EventUtility.getActivePart();
+        if(activePart!=null && activePart.getObject()!=null
+                && activePart.getObject() instanceof IE4SavablePart){
+            return activePart.getObject();
         }
         return null;
     }
 
-    public static DetailsViewPart getDetailsView() {
-        return (DetailsViewPart) getView(DetailsViewPart.ID, false);
-    }
-
-    public static void refreshDetailsViewer() {
-        if (getDetailsView() != null) {
-            ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
+    public static DetailsPartE4 getDetailsView(EPartService partService) {
+        MPart part = partService.findPart("eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4");
+        if(part!=null){
+            return (DetailsPartE4) part.getObject();
         }
+        return null;
     }
 
-    public static void reflowDetailsViewer() {
-        if (getDetailsView() != null) {
-            ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
+    public static void refreshDetailsViewer(EPartService partService) {
+        if (getDetailsView(partService) != null) {
+            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).refresh();
         }
     }
 
-    public static SupplementalDataViewPart getSupplementalDataView() {
-        return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
-                false);
-    }
-
-    public static void reflowSupplementalViewer() {
-        if (getSupplementalDataView() != null) {
-            ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
-            .reflow();
+    public static void reflowDetailsViewer(EPartService partService) {
+        if (getDetailsView(partService) != null) {
+            ((AbstractCdmDataViewerE4) getDetailsView(partService).getViewer()).reflow();
         }
     }
 
@@ -621,7 +457,7 @@ public abstract class AbstractUtility {
             if(depth>0){
                 indentString += "- ";
             }
-            result.put(node.term, indentString + node.term.getMessage());
+            result.put(node.term, indentString + node.term.getLabel());
             parseTermTree(node.children, result, depth);
         }
     }
@@ -733,52 +569,269 @@ public abstract class AbstractUtility {
 
         @Override
         public int compareTo(TermNode<T> that) {
-            return this.term.getMessage().compareTo(that.term.getMessage());
-        }
-    }
-
-
-    public static void executeCommand(String commandId, Object source, String pluginId) {
-        IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
-        Exception exception = null;
-        try {
-            handlerService.executeCommand(commandId, null);
-        } catch (ExecutionException e) {
-            exception = e;
-        } catch (NotDefinedException e) {
-            exception = e;
-        } catch (NotEnabledException e) {
-            exception = e;
-        } catch (NotHandledException e) {
-            exception = e;
-        } finally {
-            if(exception != null) {
-                MessagingUtils.errorDialog("Error executing command",
-                        source,
-                        "Could not execute command with id " + commandId ,
-                        pluginId,
-                        exception,
-                        true);
-            }
+            return this.term.getLabel().compareTo(that.term.getLabel());
         }
     }
 
-    /**
-     * @param event
-     * @return
-     */
     public static Object getElementsFromSelectionChangedEvent(SelectionChangedEvent event) {
         IStructuredSelection selection = (IStructuredSelection) event.getSelection();
-        Object selectionToSet;
+        Object selectionToSet = selection;
         if(selection.size() == 1){
             selectionToSet = selection.getFirstElement();
         }
         else if(!selection.isEmpty()){
             selectionToSet = selection.toArray();
         }
-        else{
-            selectionToSet = selection;
-        }
         return selectionToSet;
     }
-}
+
+    /**
+     * Executes a remoting monitored import
+     *
+     * @param label for the import
+     * @param uuid of the remoting monitor already started on the server
+     * @param pollInterval in milliseconds
+     * @param cancelable flag which determines whether the operation can be cancelled
+     * @param postOp callback for running post operation logic
+     * @return
+     */
+    public static IStatus executeMoniteredOperation(final String label,
+            final UUID uuid,
+            final int pollInterval,
+            final boolean cancelable,
+            final IPostMoniteredOperationEnabled postOp,
+            final IFeedbackGenerator feedbackGenerator,
+            final boolean showResult,
+            final boolean updateNavigator) {
+
+       try{
+               // get the remoting monitor the first time to make sure that the
+            // operation is valid
+            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
+            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+            if(firstRemotingMonitor == null) {
+                throw new IllegalStateException("Remoting progress monitor is null");
+            }
+            if (firstRemotingMonitor.isDone()){
+                createResult(label, showResult, firstRemotingMonitor);
+                Set<Taxon> taxaToUpdate = getTaxaToUpdate(firstRemotingMonitor);
+                updateNameEditors(taxaToUpdate);
+                return Status.OK_STATUS;
+            }
+
+            Job job = new Job(label) {
+                @Override
+                public IStatus run(IProgressMonitor monitor) {
+                    // run the monitor until the operation is finished
+                    SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
+
+
+                    IRemotingProgressMonitor remotingMonitor;
+                    try {
+                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
+                                uuid,
+                                pollInterval,
+                                postOp,
+                                feedbackGenerator,
+                                subMonitor);
+                    } catch (Exception ex) {
+                        return new Status(IStatus.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
+                    }
+
+                    // collect reports
+//                         for(String report : remotingMonitor.getResult()) {
+                    createResult(label, showResult, remotingMonitor);
+                    Set<Taxon> taxaToUpdate = getTaxaToUpdate(remotingMonitor);
+                    updateNameEditors(taxaToUpdate);
+                    if (!taxaToUpdate.isEmpty() && updateNavigator){
+                        refreshNavigator();
+                    }
+                    return Status.OK_STATUS;
+                }
+
+                private void refreshNavigator() {
+                    EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAVIGATOR, true);
+                }
+
+                @Override
+                protected void canceling() {
+                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
+                }
+            };
+
+            // configure the job
+            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
+
+            job.setUser(true);
+            // schedule job
+            job.schedule();
+
+        } catch (Exception e) {
+            MessagingUtils.errorDialog("Error executing operation",
+                    AbstractUtility.class,
+                    "An error occurred while executing " + label,
+                    TaxeditorStorePlugin.PLUGIN_ID,
+                    e,
+                    true);
+        }
+
+        return Status.OK_STATUS;
+    }
+
+    private static Set<Taxon> getTaxaToUpdate(IRemotingProgressMonitor remotingMonitor) {
+        Set<Taxon> taxaToUpdate = new HashSet<>();
+        if (remotingMonitor.getResult() instanceof UpdateResult){
+            for (CdmBase object: ((UpdateResult)remotingMonitor.getResult()).getUpdatedObjects()){
+                Taxon taxon = null;
+
+                if (object instanceof Taxon){
+                    taxon = HibernateProxyHelper.deproxy(object, Taxon.class);
+                }else if (object instanceof Synonym){
+                    Synonym syn = HibernateProxyHelper.deproxy(object, Synonym.class);
+                    taxon = syn.getAcceptedTaxon();
+                }else if (object instanceof TaxonNode){
+                    taxon = ((TaxonNode)object).getTaxon() != null? ((TaxonNode)object).getTaxon():null;
+                }
+                if (taxon != null){
+                    taxaToUpdate.add(taxon);
+                }
+            }
+        }
+        return taxaToUpdate;
+    }
+    public static void createResult(String label, boolean showResult,
+            IRemotingProgressMonitor remotingMonitor) {
+        final StringBuilder reportSb = new StringBuilder();
+        if (remotingMonitor.getResult() instanceof ExportResult) {
+            reportSb.append(((ExportResult)remotingMonitor.getResult()).createReport());
+        }else if (remotingMonitor.getResult() instanceof UpdateResult){
+            if (((UpdateResult)remotingMonitor.getResult()).isOk()){
+                int count = ((UpdateResult)remotingMonitor.getResult()).getUpdatedObjects().size();
+                if (count == 0){
+                    count = ((UpdateResult)remotingMonitor.getResult()).getUpdatedCdmIds().size();
+                }
+
+                reportSb.append("Update successful. \n"+"Updated Objects: " +count);
+            }
+            if (!((UpdateResult)remotingMonitor.getResult()).getExceptions().isEmpty()){
+                reportSb.append(((UpdateResult)remotingMonitor.getResult()).getExceptions().toString());
+            }
+        }else if (remotingMonitor.getReports()!= null){
+            for (String o:remotingMonitor.getReports()){
+                reportSb.append(o);
+            }
+        }
+        if(showResult && !StringUtils.isBlank(reportSb.toString()) && reportSb.length() != 0) {
+            Display.getDefault().asyncExec(new Runnable() {
+                @Override
+                public void run() {
+                    // display reports with possibility to save
+                    ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+                    dialog.setTitle(label + " Report");
+                    dialog.setReportText(reportSb.toString());
+                    dialog.open();
+                }
+            });
+        }
+    }
+
+    private static void createExportResult(final String label, String urlString, boolean createZip,
+            IRemotingProgressMonitor remotingMonitor) {
+
+        final StringBuilder reportSb = new StringBuilder();
+        if (remotingMonitor.getResult() instanceof ExportResult){
+            ExportResult result = (ExportResult)remotingMonitor.getResult();
+
+            reportSb.append(result.createReport());
+
+            if(!StringUtils.isBlank(reportSb.toString())) {
+                Display.getDefault().asyncExec(new Runnable() {
+                    @Override
+                    public void run() {
+                        // display reports with possibility to save
+                        ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+                        dialog.setTitle(label + " Report");
+                        dialog.setReportText(reportSb.toString());
+                        dialog.open();
+                    }
+                });
+            }
+
+            if (urlString != null){
+                 ExportDataWrapper<?> data = result.getExportData();
+                 try{
+                     if (result.getExportData().getType().equals(ExportResultType.BYTE_ARRAY)){
+                         byte[] exportData = (byte[])data.getExportData();
+                         if(exportData != null){
+                             File file = new File(urlString);
+                             FileOutputStream stream = new FileOutputStream(file);
+                             Writer out = new BufferedWriter(new OutputStreamWriter(
+                                    stream, "UTF8"));
+
+                            stream.write(exportData);
+                            out.flush();
+                            stream.close();
+                         }
+                     } else if (result.getExportData().getType().equals(ExportResultType.MAP_BYTE_ARRAY)){
+                         Map<String, byte[]> resultMap = (Map<String, byte[]>)data.getExportData();
+                         Set<String> keySet = resultMap.keySet();
+                         SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
+                         Calendar cal = Calendar.getInstance();
+                         String fileEnding = ".csv";
+
+                         if (createZip){
+//                             File file = new File(urlString+File.separator +  sdf.format(cal.getTime())+ ".zip");
+                             File file = new File(urlString+ ".zip");
+                             FileOutputStream stream = new FileOutputStream(file);
+                             ZipOutputStream zos = new ZipOutputStream(stream);
+                             for (String key: keySet){
+                                byte[] fileData = resultMap.get(key);
+                                ZipEntry entry = new ZipEntry( key + fileEnding);
+                                zos.putNextEntry(entry);
+                                zos.write(fileData);
+                                zos.closeEntry();
+                             }
+                             zos.close();
+                         }else{
+                            if(result.getExportType().equals(ExportType.DWCA)){
+
+                                File file = new File(urlString);
+                                FileOutputStream stream = new FileOutputStream(file);
+                                ZipOutputStream zos = new ZipOutputStream(stream);
+                                for (String key: keySet){
+                                    byte[] fileData = resultMap.get(key);
+                                    ZipEntry entry = new ZipEntry( key);
+                                        zos.putNextEntry(entry);
+                                        zos.write(fileData);
+                                        zos.closeEntry();
+                                 }
+                                 zos.close();
+                              }else{
+                                 for (String key: keySet){
+                                     byte[] fileData = resultMap.get(key);
+                                     File file = new File(urlString+File.separator + key + fileEnding);
+                                     FileOutputStream stream = new FileOutputStream(file);
+                                     Writer out = new BufferedWriter(new OutputStreamWriter(
+                                            stream, "UTF8"));
+                                     stream.write(fileData);
+                                     stream.close();
+                                 }
+                              }
+                         }
+                    }else{
+                         logger.error("This kind of result data is not supported yet." + result.getExportData().getType().toString());
+                     }
+                 } catch(Exception e){
+                     logger.error(e.getStackTrace());
+                 }
+            }
+        }
+    }
+    public static void updateNameEditors(Set<Taxon> taxaToUpdate){
+        for (Taxon tax: taxaToUpdate){
+            if (tax != null){
+                EventUtility.postEvent(WorkbenchEventConstants.REFRESH_NAME_EDITOR, tax.getUuid());
+            }
+        }
+    }
+}
\ No newline at end of file