Merge branch 'develop' into remoting-4.0
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / AbstractUtility.java
index 3072f460e780d09b9192018d6021e66136bce989..560fd61f04b8dc701883df406c8c9934b2940eb4 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$
 /**
  * Copyright (C) 2007 EDIT
- * European Distributed Institute of Taxonomy 
+ * European Distributed Institute of Taxonomy
  * http://www.e-taxonomy.eu
- * 
+ *
  * 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.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.TreeSet;
 
-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.ILog;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
@@ -25,7 +32,6 @@ import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.resource.ColorRegistry;
 import org.eclipse.jface.resource.FontRegistry;
@@ -42,6 +48,7 @@ import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 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.IProgressService;
@@ -49,9 +56,10 @@ import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
 import org.eclipse.ui.themes.ITheme;
 import org.eclipse.ui.themes.IThemeManager;
 
-import eu.etaxonomy.cdm.model.common.TermBase;
+import eu.etaxonomy.cdm.model.common.IEnumTerm;
 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
+import eu.etaxonomy.taxeditor.operation.RemotingCdmHandler;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
 import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
 import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
@@ -61,21 +69,22 @@ import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
  * <p>
  * Abstract AbstractUtility class.
  * </p>
- * 
+ *
  * @author n.hoffmann
  * @created 11.05.2009
  * @version 1.0
  */
 public abstract class AbstractUtility {
 
-       /** Constant <code>statusLineManager</code> */
-       protected static IStatusLineManager statusLineManager;
+    /** Constant <code>statusLineManager</code> */
+    protected static IStatusLineManager statusLineManager;
+
 
        /**
         * <p>
         * closeAll
         * </p>
-        * 
+        *
         * @return a boolean.
         */
        public static boolean closeAll() {
@@ -84,7 +93,7 @@ public abstract class AbstractUtility {
 
        /**
         * Close the given editor.
-        * 
+        *
         * @param editor
         *            The <tt>MultipageTaxonEditor</tt> to close.
         * @return <tt>true</tt> on success
@@ -97,7 +106,7 @@ public abstract class AbstractUtility {
         * <p>
         * getShell
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.swt.widgets.Shell} object.
         */
        public static Shell getShell() {
@@ -110,7 +119,7 @@ public abstract class AbstractUtility {
         * <p>
         * getActivePage
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.ui.IWorkbenchPage} object.
         */
        public static IWorkbenchPage getActivePage() {
@@ -123,7 +132,7 @@ public abstract class AbstractUtility {
         * <p>
         * getActivePart
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.ui.IWorkbenchPart} object.
         */
        public static IWorkbenchPart getActivePart() {
@@ -138,7 +147,7 @@ public abstract class AbstractUtility {
         * <p>
         * getWorkbenchWindow
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
         */
        public static ApplicationWindow getWorkbenchWindow() {
@@ -152,7 +161,7 @@ public abstract class AbstractUtility {
         * <p>
         * showView
         * </p>
-        * 
+        *
         * @param id
         *            a {@link java.lang.String} object.
         * @return a {@link org.eclipse.ui.IViewPart} object.
@@ -163,7 +172,7 @@ public abstract class AbstractUtility {
                                        .getActivePage()
                                        .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
                } catch (PartInitException e) {
-                       errorDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
+                       MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
                        return null;
                }
        }
@@ -172,7 +181,7 @@ public abstract class AbstractUtility {
         * <p>
         * hideView
         * </p>
-        * 
+        *
         * @param view
         *            a {@link org.eclipse.ui.IViewPart} object.
         */
@@ -185,7 +194,7 @@ public abstract class AbstractUtility {
         * <p>
         * getView
         * </p>
-        * 
+        *
         * @param id
         *            a {@link java.lang.String} object.
         * @param restore
@@ -207,7 +216,7 @@ public abstract class AbstractUtility {
         * <p>
         * getService
         * </p>
-        * 
+        *
         * @param api
         *            a {@link java.lang.Class} object.
         * @return a {@link java.lang.Object} object.
@@ -220,7 +229,7 @@ public abstract class AbstractUtility {
         * <p>
         * getCurrentTheme
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.ui.themes.ITheme} object.
         */
        public static ITheme getCurrentTheme() {
@@ -233,7 +242,7 @@ public abstract class AbstractUtility {
         * 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() {
@@ -244,7 +253,7 @@ public abstract class AbstractUtility {
         * <p>
         * getFont
         * </p>
-        * 
+        *
         * @param symbolicName
         *            a {@link java.lang.String} object.
         * @return a {@link org.eclipse.swt.graphics.Font} object.
@@ -257,7 +266,7 @@ public abstract class AbstractUtility {
         * 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() {
@@ -268,7 +277,7 @@ public abstract class AbstractUtility {
         * <p>
         * getColor
         * </p>
-        * 
+        *
         * @param symbolicName
         *            a {@link java.lang.String} object.
         * @return a {@link org.eclipse.swt.graphics.Color} object.
@@ -277,173 +286,14 @@ public abstract class AbstractUtility {
                return getColorRegistry().get(symbolicName);
        }
 
-       /**
-        * Open a message box that informs the user about unimplemented
-        * functionality. This method is for developer convenience.
-        * 
-        * @param source
-        *            a {@link java.lang.Object} object.
-        */
-       public static void notImplementedMessage(Object source) {
-               warningDialog("Not yet implemented", source,
-                               "This functionality is not yet implemented.");
-       }
-
-       /**
-        * <p>
-        * informationDialog
-        * </p>
-        * 
-        * @param title
-        *            a {@link java.lang.String} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void informationDialog(final String title,
-                       final String message) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       public void run() {
-                               MessageDialog.openInformation(getShell(), title, message);
-                       }
-               });
-       }
-
-       public static void informationDialog(final String title,
-                       final IStatus status) {
-               informationDialog(title, status.getMessage());
-       }
-       
-       /**
-        * <p>
-        * warningDialog
-        * </p>
-        * 
-        * @param title
-        *            The dialogs title
-        * @param source
-        *            The object where the warning was generated (used by log4j)
-        * @param message
-        *            An informative String to be presented to the user
-        */
-       public static void warningDialog(final String title, final Object source,
-                       final String message) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       public void run() {
-                               MessageDialog.openWarning(getShell(), title, message);
-                               Class<? extends Object> clazz = source != null ? source
-                                               .getClass() : AbstractUtility.class;
-                               warn(clazz, message);
-                       }
-               });
-       }
-       
-       /**
-        * @param title
-        * @param termBase
-        * @param status
-        */
-       public static void warningDialog(String title, Object source,
-                       IStatus status) {
-               warningDialog(title, source, status.getMessage());
-       }
-
-       /**
-        * <p>
-        * errorDialog
-        * </p>
-        * 
-        * @param title
-        *            The dialogs title
-        * @param source
-        *            The object where the warning was generated (used by log4j)
-        * @param message
-        *            An informative String to be presented to the user
-        * @param title
-        *            The dialogs title
-        * @param t
-        *            a Throwable if one exists or null
-        */
-       public static void errorDialog(final String title, final Object source,
-                       final String message, final Throwable t) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       public void run() {
-                               MessageDialog.openError(getShell(), title, message + getCauseRecursively(t));
-                               Class<? extends Object> clazz = source != null ? source
-                                               .getClass() : this.getClass();
-                               error(clazz, message, t);
-                       }
-
-                       private String getCauseRecursively(Throwable t) {
-                               if(t == null){
-                                       return null;
-                               }
-                               
-                               if(t.getCause() != null){
-                                       return getCauseRecursively(t.getCause());
-                               }else{
-                                       return String.format("\n\nException: %s\nMessage: %s", t.getClass().getSimpleName(), t.getMessage());
-                               }
-
-                       }
-               });
-       }
-       
-       public static void errorDialog(final String title, final Object source,
-                       final String message){
-               errorDialog(title, source, message, null);
-       }
-
-       /**
-        * <p>
-        * errorDialog
-        * </p>
-        * 
-        * @param title
-        *            a {@link java.lang.String} object.
-        * @param source
-        *            a {@link java.lang.Object} object.
-        * @param status
-        *            a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static void errorDialog(final String title, final Object source,
-                       final IStatus status) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       public void run() {
-                               MessageDialog.openError(getShell(), title, status.getMessage());
-                               Class<? extends Object> clazz = source != null ? source
-                                               .getClass() : this.getClass();
-                               error(clazz, status.getMessage(), status.getException());
-                       }
-               });
-       }
-
-       /**
-        * <p>
-        * confirmDialog
-        * </p>
-        * 
-        * @param title
-        *            a {@link java.lang.String} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        * @return a boolean.
-        */
-       public static boolean confirmDialog(String title, String message) {
-               return MessageDialog.openQuestion(getShell(), title, message);
-       }
-
        /**
         * <p>
         * executeOperation
         * </p>
-        * 
+        *
         * @param operation
         *            a
-        *            {@link eu.etaxonomy.taxeditor.operation.AbstractPostOperation}
+        *            {@link eu.etaxonomy.taxeditor.operation.AbstractPostTaxonOperation}
         *            object.
         * @return a {@link org.eclipse.core.runtime.IStatus} object.
         */
@@ -458,23 +308,27 @@ public abstract class AbstractUtility {
 
                IRunnableWithProgress runnable = new IRunnableWithProgress() {
 
-                       public void run(IProgressMonitor monitor)
+                       @Override
+            public void run(IProgressMonitor monitor)
                                        throws InvocationTargetException, InterruptedException {
-                               monitor.beginTask(operation.getLabel(), 100);
+                               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);
                                } catch (ExecutionException e) {
-                                       errorDialog("Error executing operation", getClass(), String.format("An error occured while executing %s.", operation.getLabel()), e);
+
+                                       MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+
                                } finally {
                                        monitor.done();
                                }
-                               
+
                                String statusString = status.equals(Status.OK_STATUS) ? "completed"
                                                : "cancelled";
-                               setStatusLine(operation.getLabel() + " " + statusString + ".");
+                               setStatusLine(operationlabel + " " + statusString + ".");
 
                        }
                };
@@ -482,40 +336,9 @@ public abstract class AbstractUtility {
                try {
                        runInUI(runnable, null);
                } catch (Exception e) {
-                       errorDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+                       MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
                }
 
-               // // Start the main progress monitor.
-               // IProgressMonitor newMonitor =
-               // startMainMonitor(getMonitor(),operation.getLabel(), 100);
-               //
-               // // Check whether operation was canceled and do some steps.
-               // workedChecked(newMonitor, 10);
-               //
-               // try {
-               // IStatus status = getOperationHistory().execute(operation, newMonitor,
-               // WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
-               //
-               // // Check whether operation was canceled and do some steps.
-               // workedChecked(newMonitor, 30);
-               //
-               // String statusString = status.equals(Status.OK_STATUS) ? "completed" :
-               // "cancelled";
-               // setStatusLine(operation.getLabel() + " " + statusString + ".");
-               //
-               // return status;
-               // } catch (ExecutionException e) {
-               // logger.error("Error executing operation: " + operation.getLabel(),
-               // e);
-               // errorDialog("Error executing operation: " + operation.getLabel(),
-               // "Please refer to the error log.");
-               // }
-               // finally {
-               //
-               // // Stop the progress monitor.
-               // newMonitor.done();
-               // }
-
                IPostOperationEnabled postOperationEnabled = operation
                                .getPostOperationEnabled();
                if (postOperationEnabled != null) {
@@ -524,11 +347,56 @@ public abstract class AbstractUtility {
                return Status.OK_STATUS;
        }
 
+          public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
+               if (getOperationHistory() == null) {
+                   throw new IllegalArgumentException(
+                           "There is no operation history for this context");
+               }
+
+               final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
+                       .getUIInfoAdapter(getShell());
+
+               IRunnableWithProgress runnable = new IRunnableWithProgress() {
+
+                   @Override
+                   public void run(IProgressMonitor monitor)
+                           throws InvocationTargetException, InterruptedException {
+                       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);
+                           if(handler != null) {
+                               handler.postOperation(status);
+                           }
+                       } catch (ExecutionException e) {
+                           MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+                       } finally {
+                           monitor.done();
+                       }
+
+                       String statusString = status.equals(Status.OK_STATUS) ? "completed"
+                               : "cancelled";
+                       setStatusLine(operationlabel + " " + statusString + ".");
+
+                   }
+               };
+
+               try {
+                   runInUI(runnable, null);
+               } catch (Exception e) {
+                   MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+               }
+
+               return Status.OK_STATUS;
+           }
        /**
         * <p>
         * getOperationHistory
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
         *         object.
         */
@@ -540,14 +408,15 @@ public abstract class AbstractUtility {
         * <p>
         * setStatusLine
         * </p>
-        * 
+        *
         * @param message
         *            a {@link java.lang.String} object.
         */
        public static void setStatusLine(final String message) {
                Display.getDefault().asyncExec(new Runnable() {
 
-                       public void run() {
+                       @Override
+            public void run() {
                                statusLineManager.setMessage(message);
                        }
 
@@ -559,7 +428,7 @@ public abstract class AbstractUtility {
         * <p>
         * getMonitor
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
         */
        public static IProgressMonitor getMonitor() {
@@ -570,7 +439,7 @@ public abstract class AbstractUtility {
        /**
         * Starts either the given {@link IProgressMonitor} if it's not
         * <code>null</code> or a new {@link NullProgressMonitor}.
-        * 
+        *
         * @param progressMonitor
         *            The {@link IProgressMonitor} or <code>null</code> if no
         *            progress should be reported.
@@ -595,7 +464,7 @@ public abstract class AbstractUtility {
         * Creates a {@link SubProgressMonitor} if the given
         * {@link IProgressMonitor} is not <code>null</code> and not a
         * {@link NullProgressMonitor}.
-        * 
+        *
         * @param progressMonitor
         *            The parent {@link IProgressMonitor} of the
         *            {@link SubProgressMonitor} to be created.
@@ -620,7 +489,7 @@ public abstract class AbstractUtility {
        /**
         * Checks whether the user canceled this operation. If not canceled, the
         * given number of steps are declared as done.
-        * 
+        *
         * @param newMonitor
         *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
         * @param steps
@@ -637,7 +506,7 @@ public abstract class AbstractUtility {
 
        /**
         * Present a progress dialog to the user. This dialog will block the UI
-        * 
+        *
         * @param runnable
         *            an implementation of {@link IRunnableWithProgress}
         * @throws java.lang.InterruptedException
@@ -654,7 +523,7 @@ public abstract class AbstractUtility {
         * <p>
         * runInUI
         * </p>
-        * 
+        *
         * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
         * @param runnable
         *            a {@link org.eclipse.jface.operation.IRunnableWithProgress}
@@ -677,7 +546,7 @@ public abstract class AbstractUtility {
         * <p>
         * run
         * </p>
-        * 
+        *
         * @param fork
         *            a boolean.
         * @param cancelable
@@ -700,7 +569,7 @@ public abstract class AbstractUtility {
         * <p>
         * getProgressService
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.ui.progress.IProgressService} object.
         */
        public static IProgressService getProgressService() {
@@ -712,7 +581,7 @@ public abstract class AbstractUtility {
         * <p>
         * getProgressService2
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
         *         object.
         */
@@ -720,132 +589,11 @@ public abstract class AbstractUtility {
                return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
        }
 
-       /**
-        * <p>
-        * info
-        * </p>
-        * 
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void info(String message) {
-               IStatus status = new Status(IStatus.INFO, getPluginId(), message);
-               info(status);
-       }
-
-       /**
-        * <p>
-        * info
-        * </p>
-        * 
-        * @param status
-        *            a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static void info(IStatus status) {
-               log(status);
-       }
-
-       /**
-        * <p>
-        * warn
-        * </p>
-        * 
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void warn(Class source, String message) {
-               IStatus status = new Status(IStatus.WARNING, getPluginId(), message);
-               getLog4JLogger(source).warn(message);
-               log(status);
-       }
-       
-       public static void warn(Class source, IStatus status) {
-               getLog4JLogger(source).warn(status.getMessage(), status.getException());
-               log(status);
-       }
-       
-       public static void warn(Class source, Throwable t) {
-               IStatus status = new Status(IStatus.WARNING, getPluginId(), t.getMessage(), t);
-               getLog4JLogger(source).warn(t);
-               log(status);
-       }
-
-       /**
-        * <p>
-        * error
-        * </p>
-        * 
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param t
-        *            a {@link java.lang.Throwable} object.
-        */
-       public static void error(Class source, Throwable t) {
-               error(source.getClass(), t.getMessage(), t);
-       }
-
-       /**
-        * <p>
-        * error
-        * </p>
-        * 
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        * @param t
-        *            a {@link java.lang.Throwable} object.
-        */
-       public static void error(Class source, String message, Throwable t) {
-               IStatus status = new Status(IStatus.ERROR, getPluginId(), message, t);
-               error(source, status);
-       }
-
-       /**
-        * <p>
-        * error
-        * </p>
-        * 
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param status
-        *            a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static void error(Class source, IStatus status) {
-               getLog4JLogger(source)
-                               .error(status.getMessage(), status.getException());
-               log(status);
-       }
-
-       /**
-        * <p>
-        * getLog4JLogger
-        * </p>
-        * 
-        * @param clazz
-        *            a {@link java.lang.Class} object.
-        * @return a {@link org.apache.log4j.Logger} object.
-        */
-       public static Logger getLog4JLogger(Class clazz) {
-               return Logger.getLogger(clazz);
-       }
-
-       /**
-        * @see {@link ILog#log(IStatus)}
-        * 
-        * @param status
-        */
-       private static void log(IStatus status) {
-               TaxeditorStorePlugin.getDefault().getLog().log(status);
-       }
-
        /**
         * <p>
         * getPluginId
         * </p>
-        * 
+        *
         * @return a {@link java.lang.String} object.
         */
        public static String getPluginId() {
@@ -856,7 +604,7 @@ public abstract class AbstractUtility {
         * <p>
         * getActiveEditor
         * </p>
-        * 
+        *
         * @return a {@link org.eclipse.ui.IEditorPart} object.
         */
        public static IEditorPart getActiveEditor() {
@@ -868,7 +616,7 @@ public abstract class AbstractUtility {
         * <p>
         * getDetailsView
         * </p>
-        * 
+        *
         * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
         *         object.
         */
@@ -909,5 +657,198 @@ public abstract class AbstractUtility {
                                        .reflow();
                }
        }
-       
-       }
+
+
+    /**
+     * Orders a Collection of {@link IEnumTerm}s according to the term
+     * hierarchy. <br>
+     * <br>
+     * The returned map will be be ordered primarily by root elements,
+     * secondarily by the child elements and their children resp., both ascending alphabetically. <br>
+     * @param terms
+     *            A {@link Collection} of {@link IEnumTerm}s for which the term
+     *            hierarchy should be created
+     * @return a map which holds the terms as keys and their string
+     *         representation via {@link IEnumTerm#getMessage()} as values
+     */
+    public static <T extends IEnumTerm<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
+        TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
+        parentElements.addAll(getTermHierarchy(terms));
+
+        // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
+        LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
+        parseTermTree(parentElements, result, -1);
+        return result;
+    }
+
+    private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
+        depth++;
+        for(TermNode<T> node:children){
+            String indentString = "";
+            for(int i=0;i<depth;i++){
+                indentString += "  ";
+            }
+            if(depth>0){
+                indentString += "- ";
+            }
+            result.put(node.term, indentString + node.term.getMessage());
+            parseTermTree(node.children, result, depth);
+        }
+    }
+
+    private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
+        List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
+        for(T term:terms){
+            // only terms with parents
+            if(term.getKindOf()!=null){
+                TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
+                TermNode<T> childNode = new TermNode<T>(term);
+                if(parents.contains(parentNode)){
+                    // parent found in parent list -> add this term to parent's child list
+                    parents.get(parents.indexOf(parentNode)).addChild(childNode);
+                    if(!term.getGeneralizationOf().isEmpty()){
+                        // has more children -> add to list which will be the parent for the next recursion
+                        hasChildrenList.add(childNode);
+                    }
+                }
+            }
+        }
+        if(!hasChildrenList.isEmpty()){
+            addToParents(hasChildrenList, terms);
+        }
+    }
+
+    private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
+        List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
+        // get root elements
+        for(T term:terms){
+            T parentTerm = term.getKindOf();
+            if(parentTerm==null){
+                // root element
+                parents.add(new TermNode<T>(term));
+            }
+        }
+        addToParents(parents, terms);
+        return parents;
+    }
+
+    @SuppressWarnings("unchecked")
+    /**
+     * Recursively iterates over all term parents until no more parent is found i.e. the root node
+     * @param term The term for which the parent should be found
+     * @return the root terms of the term hierarchy
+     */
+    private static<T extends IEnumTerm<T>> T getParentFor(T term){
+        // PP: cast should be safe. Why is Eclipse complaining??
+        T parent = term.getKindOf();
+        if(parent==null){
+            return term;
+        }
+        else{
+            return getParentFor(term.getKindOf());
+        }
+    }
+
+    private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
+        private final T term;
+        private final TreeSet<TermNode<T>> children;
+
+        /**
+         * @param term
+         * @param children
+         */
+        public TermNode(T term) {
+            super();
+            this.term = term;
+            this.children = new TreeSet<TermNode<T>>();
+        }
+
+        public void addChild(TermNode<T> child){
+            this.children.add(child);
+        }
+
+        /**
+         * @return the children
+         */
+        public TreeSet<TermNode<T>> getChildren() {
+            return children;
+        }
+
+        /**
+         * @return the term
+         */
+        public T getTerm() {
+            return term;
+        }
+
+        /* (non-Javadoc)
+         * @see java.lang.Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((term == null) ? 0 : term.hashCode());
+            return result;
+        }
+
+        /* (non-Javadoc)
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            TermNode other = (TermNode) obj;
+            if (term == null) {
+                if (other.term != null) {
+                    return false;
+                }
+            } else if (!term.equals(other.term)) {
+                return false;
+            }
+            return true;
+        }
+
+        /* (non-Javadoc)
+         * @see java.lang.Comparable#compareTo(java.lang.Object)
+         */
+        @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);
+            }
+        }
+    }
+}