Improve error notifications.
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 29 Apr 2015 21:02:47 +0000 (21:02 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 29 Apr 2015 21:02:47 +0000 (21:02 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8084 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.cms/src/org/argeo/cms/CmsApplication.java
org.argeo.cms/src/org/argeo/cms/util/CmsUtils.java
org.argeo.cms/src/org/argeo/cms/util/SystemNotifications.java [new file with mode: 0644]

index fdf2e0270d2214da402030197fcb369c75fa5957..74b3b6b03d8007b4a1d1eec841edc97af1d4235a 100644 (file)
@@ -2,8 +2,6 @@ package org.argeo.cms;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -18,13 +16,13 @@ import javax.jcr.Session;
 import javax.jcr.security.Privilege;
 import javax.jcr.version.VersionManager;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.auth.LoginRequiredException;
 import org.argeo.cms.internal.ImageManagerImpl;
 import org.argeo.cms.util.BundleResourceLoader;
 import org.argeo.cms.util.CmsUtils;
+import org.argeo.cms.util.SystemNotifications;
 import org.argeo.jcr.JcrUtils;
 import org.eclipse.gemini.blueprint.context.BundleContextAware;
 import org.eclipse.rap.rwt.RWT;
@@ -41,8 +39,6 @@ import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 import org.osgi.framework.BundleContext;
 
 /** Configures an Argeo CMS RWT application. */
@@ -341,40 +337,46 @@ public class CmsApplication implements CmsConstants, ApplicationConfiguration,
                protected void refreshBody() {
                        if (bodyArea == null)
                                return;
-                       // clear
-                       for (Control child : bodyArea.getChildren())
-                               child.dispose();
-                       bodyArea.setLayout(CmsUtils.noSpaceGridLayout());
-
                        // Exception
                        Throwable exception = getException();
                        if (exception != null) {
-                               new Label(bodyArea, SWT.NONE).setText("Unreachable state : "
-                                               + getState());
-                               if (getNode() != null)
-                                       new Label(bodyArea, SWT.NONE).setText("Context : "
-                                                       + getNode());
-
-                               Text errorText = new Text(bodyArea, SWT.MULTI | SWT.H_SCROLL
-                                               | SWT.V_SCROLL);
-                               errorText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
-                                               true));
-                               StringWriter sw = new StringWriter();
-                               exception.printStackTrace(new PrintWriter(sw));
-                               errorText.setText(sw.toString());
-                               IOUtils.closeQuietly(sw);
+                               // new Label(bodyArea, SWT.NONE).setText("Unreachable state : "
+                               // + getState());
+                               // if (getNode() != null)
+                               // new Label(bodyArea, SWT.NONE).setText("Context : "
+                               // + getNode());
+                               //
+                               // Text errorText = new Text(bodyArea, SWT.MULTI | SWT.H_SCROLL
+                               // | SWT.V_SCROLL);
+                               // errorText.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
+                               // true,
+                               // true));
+                               // StringWriter sw = new StringWriter();
+                               // exception.printStackTrace(new PrintWriter(sw));
+                               // errorText.setText(sw.toString());
+                               // IOUtils.closeQuietly(sw);
+                               SystemNotifications systemNotifications = new SystemNotifications(
+                                               bodyArea);
+                               systemNotifications.notifyException(exception);
                                resetException();
+                               return;
                                // TODO report
-                       } else {
-                               String state = getState();
-                               try {
-                                       if (state == null)
-                                               throw new CmsException("State cannot be null");
-                                       uiProvider.createUi(bodyArea, getNode());
-                               } catch (RepositoryException e) {
-                                       throw new CmsException("Cannot refresh body", e);
-                               }
                        }
+
+                       // clear
+                       for (Control child : bodyArea.getChildren())
+                               child.dispose();
+                       bodyArea.setLayout(CmsUtils.noSpaceGridLayout());
+
+                       String state = getState();
+                       try {
+                               if (state == null)
+                                       throw new CmsException("State cannot be null");
+                               uiProvider.createUi(bodyArea, getNode());
+                       } catch (RepositoryException e) {
+                               throw new CmsException("Cannot refresh body", e);
+                       }
+
                        bodyArea.layout(true, true);
                }
 
index 5d31e2c51f0d68639fe64234a69027249e82f5e2..0eda74f53496be9ade00a176f3e05276c991f46c 100644 (file)
@@ -65,10 +65,12 @@ public class CmsUtils implements CmsConstants {
                return new RowData(16, 16);
        }
 
+       /** Style widget */
        public static void style(Widget widget, String style) {
                widget.setData(CmsConstants.STYLE, style);
        }
 
+       /** Enable markups on widget */
        public static void markup(Widget widget) {
                widget.setData(CmsConstants.MARKUP, true);
        }
diff --git a/org.argeo.cms/src/org/argeo/cms/util/SystemNotifications.java b/org.argeo.cms/src/org/argeo/cms/util/SystemNotifications.java
new file mode 100644 (file)
index 0000000..9d0c638
--- /dev/null
@@ -0,0 +1,128 @@
+package org.argeo.cms.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.ArgeoException;
+import org.argeo.cms.CmsStyles;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/** Shell displaying system notifications such as exceptions */
+public class SystemNotifications extends Shell implements CmsStyles,
+               MouseListener {
+       private static final long serialVersionUID = -8129377525216022683L;
+
+       private Control source;
+
+       public SystemNotifications(Control source) {
+               super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
+               setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU);
+
+               this.source = source;
+
+               // TODO UI
+               // setLocation(source.toDisplay(source.getSize().x - getSize().x,
+               // source.getSize().y));
+               setLayout(new GridLayout());
+               addMouseListener(this);
+
+               addShellListener(new ShellAdapter() {
+                       private static final long serialVersionUID = 5178980294808435833L;
+
+                       @Override
+                       public void shellDeactivated(ShellEvent e) {
+                               close();
+                               dispose();
+                       }
+               });
+
+       }
+
+       public void notifyException(Throwable exception) {
+               Composite pane = this;
+
+               Label lbl = new Label(pane, SWT.NONE);
+               lbl.setText(exception.getLocalizedMessage()
+                               + (exception instanceof ArgeoException ? "" : "("
+                                               + exception.getClass().getName() + ")") + "\n");
+               lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+               lbl.addMouseListener(this);
+               if (exception.getCause() != null)
+                       appendCause(pane, exception.getCause());
+
+               StringBuilder mailToUrl = new StringBuilder("mailto:?");
+               try {
+                       mailToUrl.append("subject=").append(
+                                       URLEncoder.encode(
+                                                       "Exception "
+                                                                       + new SimpleDateFormat("yyyy-MM-dd hh:mm")
+                                                                                       .format(new Date()), "UTF-8")
+                                                       .replace("+", "%20"));
+
+                       StringWriter sw = new StringWriter();
+                       exception.printStackTrace(new PrintWriter(sw));
+                       IOUtils.closeQuietly(sw);
+
+                       // see
+                       // http://stackoverflow.com/questions/4737841/urlencoder-not-able-to-translate-space-character
+                       String encoded = URLEncoder.encode(sw.toString(), "UTF-8").replace(
+                                       "+", "%20");
+                       mailToUrl.append("&amp;body=").append(encoded);
+               } catch (UnsupportedEncodingException e) {
+                       mailToUrl.append("&amp;body=").append("Could not encode: ")
+                                       .append(e.getMessage());
+               }
+               Label mailTo = new Label(pane, SWT.NONE);
+               CmsUtils.markup(mailTo);
+               mailTo.setText("<a href=\"" + mailToUrl + "\">Send details</a>");
+               mailTo.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
+
+               pack();
+               layout();
+
+               setLocation(source.toDisplay(source.getSize().x - getSize().x,
+                               source.getSize().y - getSize().y));
+               open();
+       }
+
+       private void appendCause(Composite parent, Throwable e) {
+               Label lbl = new Label(parent, SWT.NONE);
+               lbl.setText(" caused by: " + e.getLocalizedMessage() + " ("
+                               + e.getClass().getName() + ")" + "\n");
+               lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+               lbl.addMouseListener(this);
+               if (e.getCause() != null)
+                       appendCause(parent, e.getCause());
+       }
+
+       @Override
+       public void mouseDoubleClick(MouseEvent e) {
+       }
+
+       @Override
+       public void mouseDown(MouseEvent e) {
+               close();
+               dispose();
+       }
+
+       @Override
+       public void mouseUp(MouseEvent e) {
+       }
+
+}