fix #9629 handle OptionalDataException earlier in stack and recursive getCause()
[taxeditor.git] / eu.etaxonomy.taxeditor.application / src / main / java / eu / etaxonomy / taxeditor / ApplicationWorkbenchAdvisor.java
index cf565a622d91bb255e188cfed04337e2c97c11a3..969b31488e1ef8ec3d196d77f78711b4ce0a8c5b 100644 (file)
@@ -1,6 +1,9 @@
 package eu.etaxonomy.taxeditor;
 
 
+import java.io.OptionalDataException;
+
+import org.apache.http.NoHttpResponseException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.ui.application.IWorkbenchConfigurer;
 import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
@@ -8,51 +11,38 @@ import org.eclipse.ui.application.WorkbenchAdvisor;
 import org.eclipse.ui.application.WorkbenchWindowAdvisor;
 import org.eclipse.ui.statushandlers.AbstractStatusHandler;
 import org.eclipse.ui.statushandlers.StatusAdapter;
+import org.springframework.remoting.RemoteAccessException;
+import org.springframework.remoting.RemoteConnectFailureException;
 
+import eu.etaxonomy.cdm.database.PermissionDeniedException;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
-
-
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
+import eu.etaxonomy.taxeditor.store.CdmAuthenticationException;
 
 /**
  * <p>ApplicationWorkbenchAdvisor class.</p>
  *
  * @author n.hoffmann
- * @version $Id: $
  */
 public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
 
        private CdmStatusHandler cdmStatusHandler;
-       /*
-        * (non-Javadoc)
-        * @see org.eclipse.ui.application.WorkbenchAdvisor#createWorkbenchWindowAdvisor(org.eclipse.ui.application.IWorkbenchWindowConfigurer)
-        */
-       /** {@inheritDoc} */
+
        @Override
     public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
                        IWorkbenchWindowConfigurer configurer) {
                return new ApplicationWorkbenchWindowAdvisor(configurer);
        }
 
-
-       /*
-        * (non-Javadoc)
-        * @see org.eclipse.ui.application.WorkbenchAdvisor#getInitialWindowPerspectiveId()
-        */
-       /**
-        * <p>getInitialWindowPerspectiveId</p>
-        *
-        * @return a {@link java.lang.String} object.
-        */
        @Override
     public String getInitialWindowPerspectiveId() {
+//         if (PreferencesUtil.getBooleanValue(IPreferenceKeys.SHOW_CHECKLIST_PERSPECTIVE)){
+//             return "eu.etaxonomy.taxeditor.perspective.checklistperspective";
+//         }
+
                return "eu.etaxonomy.taxeditor.application.perspective.taxonomic";
        }
 
-       /*
-        * (non-Javadoc)
-        * @see org.eclipse.ui.application.WorkbenchAdvisor#initialize(org.eclipse.ui.application.IWorkbenchConfigurer)
-        */
-       /** {@inheritDoc} */
        @Override
     public void initialize(IWorkbenchConfigurer configurer) {
                super.initialize(configurer);
@@ -62,10 +52,6 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
                configurer.setSaveAndRestore(true);
        }
 
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.application.WorkbenchAdvisor#getWorkbenchErrorHandler()
-        */
        @Override
        public synchronized AbstractStatusHandler getWorkbenchErrorHandler() {
            if (cdmStatusHandler == null) {
@@ -74,7 +60,6 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
            return cdmStatusHandler;
        }
 
-
        /**
         * Custom status handler for handling scenarios which are
         * not handled by the editor (e.g. runtime exceptions).
@@ -84,38 +69,114 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
         * which displays a custom built error dialog.
         *
         * @author cmathew
-        *
         */
        class CdmStatusHandler extends AbstractStatusHandler {
 
-               /* (non-Javadoc)
-                * @see org.eclipse.ui.statushandlers.AbstractStatusHandler#handle(org.eclipse.ui.statushandlers.StatusAdapter, int)
-                */
+           private Throwable previousT;
+
                @Override
-               public void handle(StatusAdapter statusAdapter, int style)
-               {
+               public void handle(StatusAdapter statusAdapter, int style){
+
                    if(statusAdapter.getStatus().matches(IStatus.ERROR)) {
 
-                       IStatus status = statusAdapter.getStatus();
                        Throwable t = statusAdapter.getStatus().getException();
-                       // NOTE : Currently we only allow RuntimeExceptions since
-                       //        allowing all kinds of exceptions would also include
-                       //        those in generated status objects coming from from logging triggers
-                       //        leading to a recursive infinite loop of :
-                       //        initial exception thrown -> status handling -> dialog opening + logging of status ->
-                       //        status handling -> dialog opening + logging of status ... and so on
-                       if(t != null && t instanceof RuntimeException) {
-                               MessagingUtils.errorDialog("Unexpected error",
-                                               null,
-                                               MessagingUtils.UNEXPECTED_ERROR_MESSAGE,
-                                               statusAdapter.getStatus().getPlugin(),
-                                               t,
-                                               true);
-                       }
+                       if (t != null){
+                       // NOTE : the global status handling mechanism in the case of
+                       //        runtime exceptions is called twice, once by the application
+                       //        throwing the exception and then by the rcp logging mechanism.
+                       //        The check below is to make sure that the same exception is
+                       //        not shown twice in succession.
+                       if(previousT == t) {
+                       return;
+                   }
+                       previousT = t;
+
+                       if (t.getCause() instanceof PermissionDeniedException){
+                           MessagingUtils.informationDialog("Permission denied", MessagingUtils.PERMISSION_DENIED);
+                   }
+                       else if (t instanceof NoHttpResponseException
+                                 || t.getCause() instanceof CdmAuthenticationException
+                                 || (t.getMessage() != null && t.getMessage().contains("status code = 403"))){
+                        MessagingUtils.informationDialog("Access denied", MessagingUtils.ACCESS_DENIED);
+                    }else if (includesCause(t, OptionalDataException.class)){
+                        MessagingUtils.informationDialog("Error (OptionalDataException)",
+                                MessagingUtils.RESTART_EDITOR_MESSAGE
+                                );
+                    }else
+
+                       // NOTE : Currently we only allow RuntimeExceptions since
+                       //        allowing all kinds of exceptions would also include
+                       //        those in generated status objects coming from from logging triggers
+                       //        leading to a recursive infinite loop of :
+                       //        initial exception thrown -> status handling -> dialog opening + logging of status ->
+                       //        status handling -> dialog opening + logging of status ... and so on
+                       if(t instanceof RuntimeException &&
+                               ! "Widget is disposed".equals(t.getMessage()) &&
+                               ! handleKnownRuntimeException(t,statusAdapter.getStatus().getPlugin())) {
+
+                           MessagingUtils.errorDialog("Error",
+                                   null,
+                                   MessagingUtils.UNEXPECTED_ERROR_MESSAGE,
+                                   statusAdapter.getStatus().getPlugin(),
+                                   t,
+                                   true);
+
+                       } else if (("Widget is disposed".equals(t.getMessage()))){
+                        MessagingUtils.warn(this.getClass(), t);
+                        if (PreferencesUtil.isShowUpWidgetIsDisposedMessages()){
+                            MessagingUtils.errorDialog("Widget is disposed",
+                                    null,
+                                    MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
+                                    statusAdapter.getStatus().getPlugin(),
+                                    t,
+                                    true);
+                        }
+                    }
+                       }
                    }
                }
-       }
-
-
 
+               /**
+                * analyzes whether the
+         */
+        private <T extends Exception> boolean includesCause(Throwable t, Class<? extends Throwable> clazz) {
+            boolean result = false;
+
+            if (clazz.isAssignableFrom(t.getClass()) ){
+                return true;
+            }else if (t.getCause() != null && t.getCause() != t){
+                return includesCause(t.getCause(), clazz);
+            }
+            return result;
+        }
+
+        private boolean handleKnownRuntimeException(Throwable t, String pluginId) {
+                   if(t instanceof RemoteConnectFailureException ||
+                           t.getCause() instanceof RemoteConnectFailureException) {
+                       MessagingUtils.errorDialog("Connection Failure",
+                               null,
+                               MessagingUtils.CONNECTION_FAILURE_MESSAGE + System.getProperty("line.separator"),
+                               pluginId,
+                               t,
+                               true,
+                               false);
+                       return true;
+                   }
+                   if(t instanceof RemoteAccessException ||
+                           t.getCause() instanceof RemoteAccessException ) {
+                       MessagingUtils.errorDialog("Remote Access Error",
+                               null,
+                               MessagingUtils.REMOTE_ACCESS_FAILURE_MESSAGE + System.getProperty("line.separator"),
+                               pluginId,
+                               t,
+                               false,
+                               true);
+                       return true;
+                   }
+                   if (t instanceof CdmAuthenticationException){
+                       MessagingUtils.info("You are logged in now but you are not permitted to use the TaxEditor with the selected data source");
+                   }
+                   return false;
+               }
+       }
 }