Added copy button to popup and context info to the error trace
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / MessagingUtils.java
index 3fbc5123655c9dd0be5314ae360fd72b5b887c4b..959e49d92df4715109cbf5ca0e329b6139c91b6e 100644 (file)
@@ -8,11 +8,13 @@ import java.util.List;
 import org.apache.log4j.Logger;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.swt.widgets.Display;
 
 import eu.etaxonomy.cdm.persistence.hibernate.permission.SecurityExceptionUtils;
+import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
 
 /**
@@ -154,36 +156,74 @@ public class MessagingUtils {
         error(source.getClass(), t.getMessage(), t);
     }
 
+
+
     /**
-     * Displays a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog}.
+     * Returns a list of strings, providing info on,
+     *  - login
+     *  - editor version
+     *  - server (address + source name)
+     *  - db schema version
      *
-     * @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.
+     * @return
      */
-    private static void errorDialog(final String title,
-            final Object source,
-            final String message,
-            final IStatus status) {
+    public static List<String> getContextInfo() {
+        List<String> contextInfo = new ArrayList<String>();
+        String name = "";
+        String schemaVersion = "";
+        String server = "";
+        String version = "";
+        String login = "";
+        try {
+            version = Platform.getBundle("eu.etaxonomy.taxeditor.application").getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION);
+
+            if(CdmStore.getActiveCdmSource() != null ) {
+                login = CdmStore.getLoginManager().getAuthenticatedUser().getUsername();
+                name = CdmStore.getActiveCdmSource().getName();
+                schemaVersion = CdmStore.getActiveCdmSource().getDbSchemaVersion();
+                server = CdmStore.getActiveCdmSource().getServer();
+            }
 
-        Display.getDefault().asyncExec(new Runnable() {
+        } catch (Exception e) {
+            // Nothing to do
+        }
+        contextInfo.add("login : " + login);
+        contextInfo.add("editor version : " + version);
+        contextInfo.add("server : " + server + " / " + name);
+        contextInfo.add("schema version : " + schemaVersion);
 
-            @Override
-            public void run() {
-                CdmErrorDialog ced = new CdmErrorDialog(AbstractUtility.getShell(), title, message, status);
-                ced.open();
-                Class<? extends Object> clazz = source != null ? source.getClass() : this.getClass();
-                error(clazz, status);
-            }
-        });
+        return contextInfo;
+    }
+
+    public static String getStackTraceAndContextInfo(Throwable t, List<String> contextInfo)  {
+        StringBuffer stackTraceAndContextInfo = new StringBuffer();
+
+        for(String infoItem : contextInfo) {
+            stackTraceAndContextInfo.append(infoItem + System.getProperty("line.separator"));
+        }
+
+        StringWriter sw = new StringWriter();
+        t.printStackTrace(new PrintWriter(sw));
+
+        stackTraceAndContextInfo.append(sw.toString());
+
+        return stackTraceAndContextInfo.toString();
     }
 
+    /**
+     * Displays a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog}.
+     *
+     * @param title
+     * @param source
+     * @param t
+     * @param contextInfo
+     * @param message
+     * @param status
+     */
     private static void errorDialog(final String title,
             final Object source,
             final Throwable t,
+            final List<String> contextInfo,
             final String message,
             final MultiStatus status) {
 
@@ -191,19 +231,16 @@ public class MessagingUtils {
 
             @Override
             public void run() {
-                CdmErrorDialog ced = new CdmErrorDialog(AbstractUtility.getShell(), title, message, status);
+                String stackTraceWithContext = getStackTraceAndContextInfo(t, contextInfo);
+                CdmErrorDialog ced = new CdmErrorDialog(AbstractUtility.getShell(), title, message, status, stackTraceWithContext);
                 ced.open();
                 Class<? extends Object> clazz = source != null ? source.getClass() : this.getClass();
 
-                // Usually the status contains only the first line of the stack trace.
-                // For the unexpected messages we need the entire stack trace so we
-                // create a new status with the entire stacktrace
-                StringWriter sw = new StringWriter();
-                t.printStackTrace(new PrintWriter(sw));
+
                 IStatus singleStatus = new Status(IStatus.ERROR,
                         status.getPlugin(),
                         message,
-                        new Exception(sw.toString()));
+                        new Exception(stackTraceWithContext));
 
                 error(clazz, singleStatus);
             }
@@ -233,11 +270,19 @@ public class MessagingUtils {
         // idea of writing out the stack trace as a single string
         // leads to a single line on windows
         List<Status> childStatuses = new ArrayList<Status>();
+
+        // add context info
+        List<String> contextInfo = getContextInfo();
+        for(String infoItem : contextInfo) {
+            childStatuses.add(new Status(IStatus.ERROR, pluginId, infoItem));
+        }
+
+        // add main execption
         for (StackTraceElement ste : t.getStackTrace()) {
-            // build & add status
             childStatuses.add(new Status(IStatus.ERROR, pluginId, "at " + ste.toString()));
         }
 
+        // add cause
         if(t.getCause() != null) {
             childStatuses.add(new Status(IStatus.ERROR, pluginId, ""));
             childStatuses.add(new Status(IStatus.ERROR, pluginId, "Caused by : " + t.getCause().toString()));
@@ -247,7 +292,6 @@ public class MessagingUtils {
             }
         }
 
-        // build message with contact info
         String finalMessage = message;
 
         if(finalMessage == null || finalMessage.isEmpty()) {
@@ -255,6 +299,7 @@ public class MessagingUtils {
         }
 
         if(addContactMesg) {
+            // add edit support contact info to message
             finalMessage += MessagingUtils.CONTACT_MESSAGE;
         }
 
@@ -264,9 +309,35 @@ public class MessagingUtils {
                 t.toString(),
                 t);
 
-        errorDialog(title, source, t, finalMessage, ms);
+        errorDialog(title, source, t, contextInfo, finalMessage, ms);
     }
 
+    /**
+     * Displays a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog}.
+     *
+     * @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.
+     */
+    private static void errorDialog(final String title,
+            final Object source,
+            final String message,
+            final IStatus status) {
+
+        Display.getDefault().asyncExec(new Runnable() {
+
+            @Override
+            public void run() {
+                CdmErrorDialog ced = new CdmErrorDialog(AbstractUtility.getShell(), title, message, status);
+                ced.open();
+                Class<? extends Object> clazz = source != null ? source.getClass() : this.getClass();
+                error(clazz, status);
+            }
+        });
+    }
 
     /**
      * Displays a dialog for an exception occurring in an operation.