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 19f848b2fd61fd602b6b8faab800ce70a27380fb..969b31488e1ef8ec3d196d77f78711b4ce0a8c5b 100644 (file)
@@ -1,6 +1,8 @@
 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;
@@ -12,43 +14,26 @@ 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)){
@@ -58,11 +43,6 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
                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);
@@ -72,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) {
@@ -84,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).
@@ -94,71 +69,88 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
         * which displays a custom built error dialog.
         *
         * @author cmathew
-        *
         */
        class CdmStatusHandler extends AbstractStatusHandler {
 
            private Throwable previousT;
-               /* (non-Javadoc)
-                * @see org.eclipse.ui.statushandlers.AbstractStatusHandler#handle(org.eclipse.ui.statushandlers.StatusAdapter, int)
-                */
+
                @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 : 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(t != null && previousT == t) {
-                       return;
-                   }
-                       previousT = t;
-
-                if (t != null && ( t instanceof NoHttpResponseException || t.getCause() instanceof CdmAuthenticationException || t.getMessage().contains("status code = 403"))){
-                    MessagingUtils.informationDialog("Access denied", MessagingUtils.ACCESS_DENIED);
-
-                }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 != null &&
-                               t instanceof RuntimeException &&
-                               ! "Widget is disposed".equals(t.getMessage()) &&
-                               ! handleKnownRuntimeException(t,statusAdapter.getStatus().getPlugin())) {
-
-                           MessagingUtils.errorDialog("Unexpected error",
-                                   null,
-                                   MessagingUtils.UNEXPECTED_ERROR_MESSAGE,
-                                   statusAdapter.getStatus().getPlugin(),
-                                   t,
-                                   true);
-
-                       } else if (t != null && ("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);
-
+                       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);
+                        }
                     }
-                }
+                       }
                    }
                }
 
-               private boolean handleKnownRuntimeException(Throwable t, String pluginId) {
+               /**
+                * 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",
@@ -187,7 +179,4 @@ public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
                    return false;
                }
        }
-
-
-
 }