View Javadoc
1   package org.argeo.cms.ui.util;
2   
3   import java.io.PrintWriter;
4   import java.io.StringWriter;
5   import java.io.UnsupportedEncodingException;
6   import java.net.URLEncoder;
7   import java.text.SimpleDateFormat;
8   import java.util.Date;
9   
10  import org.apache.commons.io.IOUtils;
11  import org.argeo.cms.CmsException;
12  import org.argeo.cms.ui.CmsStyles;
13  import org.eclipse.rap.rwt.RWT;
14  import org.eclipse.swt.SWT;
15  import org.eclipse.swt.events.MouseEvent;
16  import org.eclipse.swt.events.MouseListener;
17  import org.eclipse.swt.events.ShellAdapter;
18  import org.eclipse.swt.events.ShellEvent;
19  import org.eclipse.swt.layout.GridData;
20  import org.eclipse.swt.layout.GridLayout;
21  import org.eclipse.swt.widgets.Composite;
22  import org.eclipse.swt.widgets.Control;
23  import org.eclipse.swt.widgets.Label;
24  import org.eclipse.swt.widgets.Shell;
25  
26  /** Shell displaying system notifications such as exceptions */
27  public class SystemNotifications extends Shell implements CmsStyles,
28  		MouseListener {
29  	private static final long serialVersionUID = -8129377525216022683L;
30  
31  	private Control source;
32  
33  	public SystemNotifications(Control source) {
34  		super(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
35  		setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU);
36  
37  		this.source = source;
38  
39  		// TODO UI
40  		// setLocation(source.toDisplay(source.getSize().x - getSize().x,
41  		// source.getSize().y));
42  		setLayout(new GridLayout());
43  		addMouseListener(this);
44  
45  		addShellListener(new ShellAdapter() {
46  			private static final long serialVersionUID = 5178980294808435833L;
47  
48  			@Override
49  			public void shellDeactivated(ShellEvent e) {
50  				close();
51  				dispose();
52  			}
53  		});
54  
55  	}
56  
57  	public void notifyException(Throwable exception) {
58  		Composite pane = this;
59  
60  		Label lbl = new Label(pane, SWT.NONE);
61  		lbl.setText(exception.getLocalizedMessage()
62  				+ (exception instanceof CmsException ? "" : "("
63  						+ exception.getClass().getName() + ")") + "\n");
64  		lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
65  		lbl.addMouseListener(this);
66  		if (exception.getCause() != null)
67  			appendCause(pane, exception.getCause());
68  
69  		StringBuilder mailToUrl = new StringBuilder("mailto:?");
70  		try {
71  			mailToUrl.append("subject=").append(
72  					URLEncoder.encode(
73  							"Exception "
74  									+ new SimpleDateFormat("yyyy-MM-dd hh:mm")
75  											.format(new Date()), "UTF-8")
76  							.replace("+", "%20"));
77  
78  			StringWriter sw = new StringWriter();
79  			exception.printStackTrace(new PrintWriter(sw));
80  			IOUtils.closeQuietly(sw);
81  
82  			// see
83  			// http://stackoverflow.com/questions/4737841/urlencoder-not-able-to-translate-space-character
84  			String encoded = URLEncoder.encode(sw.toString(), "UTF-8").replace(
85  					"+", "%20");
86  			mailToUrl.append("&body=").append(encoded);
87  		} catch (UnsupportedEncodingException e) {
88  			mailToUrl.append("&body=").append("Could not encode: ")
89  					.append(e.getMessage());
90  		}
91  		Label mailTo = new Label(pane, SWT.NONE);
92  		CmsUiUtils.markup(mailTo);
93  		mailTo.setText("<a href=\"" + mailToUrl + "\">Send details</a>");
94  		mailTo.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
95  
96  		pack();
97  		layout();
98  
99  		setLocation(source.toDisplay(source.getSize().x - getSize().x,
100 				source.getSize().y - getSize().y));
101 		open();
102 	}
103 
104 	private void appendCause(Composite parent, Throwable e) {
105 		Label lbl = new Label(parent, SWT.NONE);
106 		lbl.setText(" caused by: " + e.getLocalizedMessage() + " ("
107 				+ e.getClass().getName() + ")" + "\n");
108 		lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
109 		lbl.addMouseListener(this);
110 		if (e.getCause() != null)
111 			appendCause(parent, e.getCause());
112 	}
113 
114 	@Override
115 	public void mouseDoubleClick(MouseEvent e) {
116 	}
117 
118 	@Override
119 	public void mouseDown(MouseEvent e) {
120 		close();
121 		dispose();
122 	}
123 
124 	@Override
125 	public void mouseUp(MouseEvent e) {
126 	}
127 
128 }