New class for logging and dialog functionality
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / MessagingUtils.java
1 package eu.etaxonomy.taxeditor.model;
2
3 import java.io.PrintWriter;
4 import java.io.StringWriter;
5
6 import org.apache.log4j.Logger;
7 import org.eclipse.core.runtime.IStatus;
8 import org.eclipse.core.runtime.MultiStatus;
9 import org.eclipse.core.runtime.Status;
10 import org.eclipse.jface.dialogs.MessageDialog;
11 import org.eclipse.swt.widgets.Display;
12
13 import eu.etaxonomy.cdm.persistence.hibernate.permission.SecurityExceptionUtils;
14 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
15
16 /**
17 * Utility class which handles all the messaging information generated by the
18 * Editor.
19 *
20 * This includes logging as well as dialogs.
21 *
22 * @author cmathew
23 *
24 */
25 public class MessagingUtils {
26 public final static String UNEXPECTED_ERROR_MESSAGE = "This is an unexpected error.";
27 public final static String CONTACT_MESSAGE = System.getProperty("line.separator") + "Please contact EDIT Support (EditSupport@bgbm.org) with the error trace below (click on the 'Details' button).";
28
29 /**
30 * Gets the Log4J logger for a given class
31 *
32 * @param clazz
33 * a {@link java.lang.Class} object.
34 * @return a {@link org.apache.log4j.Logger} object.
35 */
36 public static Logger getLog4JLogger(Class clazz) {
37 return Logger.getLogger(clazz);
38 }
39
40 /**
41 * Logs details from a given Status object
42 *
43 * @param status
44 * a {@link org.eclipse.core.runtime.IStatus} object.
45 */
46 private static void log(IStatus status) {
47 TaxeditorStorePlugin.getDefault().getLog().log(status);
48 }
49
50 /**
51 * Logs a status object as information.
52 *
53 * @param status
54 * a {@link org.eclipse.core.runtime.IStatus} object.
55 */
56 public static void info(IStatus status) {
57 log(status);
58 }
59
60 /**
61 * Logs a string as information.
62 *
63 * @param message
64 * a {@link java.lang.String} object.
65 */
66 public static void info(String message) {
67 IStatus status = new Status(IStatus.INFO, AbstractUtility.getPluginId(), message);
68 info(status);
69 }
70
71 /**
72 * Logs an exception from a given source as a warning.
73 *
74 * @param source
75 * @param t
76 */
77 public static void warn(Class source, Throwable t) {
78 IStatus status = new Status(IStatus.WARNING, AbstractUtility.getPluginId(), t.getMessage(), t);
79 MessagingUtils.getLog4JLogger(source).warn(t);
80 log(status);
81 }
82
83 /**
84 * Logs a status object from a given source as a warning.
85 *
86 * @param source
87 * @param status
88 */
89 public static void warn(Class source, IStatus status) {
90 MessagingUtils.getLog4JLogger(source).warn(status.getMessage(), status.getException());
91 log(status);
92 }
93
94 /**
95 * Logs a string from a given source as a warning.
96 *
97 *
98 * @param source
99 * a {@link java.lang.Class} object.
100 * @param message
101 * a {@link java.lang.String} object.
102 */
103 public static void warn(Class source, String message) {
104 IStatus status = new Status(IStatus.WARNING, AbstractUtility.getPluginId(), message);
105 MessagingUtils.getLog4JLogger(source).warn(message);
106 log(status);
107 }
108
109 /**
110 * Logs a status object from a given source as an error.
111 *
112 *
113 * @param source
114 * a {@link java.lang.Class} object.
115 * @param status
116 * a {@link org.eclipse.core.runtime.IStatus} object.
117 */
118 public static void error(Class source, IStatus status) {
119 getLog4JLogger(source)
120 .error(status.getMessage(), status.getException());
121 log(status);
122 }
123
124 /**
125 * Logs a string and exception from a given source as an error.
126 *
127 *
128 * @param source
129 * a {@link java.lang.Class} object.
130 * @param message
131 * a {@link java.lang.String} object.
132 * @param t
133 * a {@link java.lang.Throwable} object.
134 */
135 public static void error(Class source, String message, Throwable t) {
136 IStatus status = new Status(IStatus.ERROR, AbstractUtility.getPluginId(), message, t);
137 error(source, status);
138 }
139
140
141
142 /**
143 * Logs an exception from a given source as an error.
144 *
145 *
146 * @param source
147 * a {@link java.lang.Class} object.
148 * @param t
149 * a {@link java.lang.Throwable} object.
150 */
151 public static void error(Class source, Throwable t) {
152 error(source.getClass(), t.getMessage(), t);
153 }
154
155 /**
156 * Displays a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog}.
157 *
158 * @param title
159 * a {@link java.lang.String} object.
160 * @param source
161 * a {@link java.lang.Object} object.
162 * @param status
163 * a {@link org.eclipse.core.runtime.IStatus} object.
164 */
165 public static void errorDialog(final String title,
166 final Object source,
167 final String message,
168 final IStatus status) {
169
170 Display.getDefault().asyncExec(new Runnable() {
171
172 @Override
173 public void run() {
174 CdmErrorDialog ced = new CdmErrorDialog(AbstractUtility.getShell(), title, message, status);
175 ced.open();
176 Class<? extends Object> clazz = source != null ? source
177 .getClass() : this.getClass();
178 error(clazz, status);
179 }
180 });
181 }
182
183 /**
184 * Displays a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog}.
185 *
186 * @param title
187 * @param source
188 * @param message
189 * @param pluginId
190 * @param t
191 */
192 public static void errorDialog(final String title,
193 final Object source,
194 final String message,
195 final String pluginId,
196 final Throwable t) {
197 // Usually the status contains only the first line of the stack trace.
198 // For the unexpected messages we need the entire stack trace so we
199 // create a new status with the entire stacktrace
200 StringWriter sw = new StringWriter();
201 t.printStackTrace(new PrintWriter(sw));
202 IStatus status = new Status(IStatus.ERROR,
203 pluginId,
204 t.getMessage(),
205 new Exception(sw.toString()));
206 errorDialog(title, source, message, status);
207 }
208
209 /**
210 * Displays a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog}.
211 *
212 * @param title
213 * a {@link java.lang.String} object.
214 * @param source
215 * a {@link java.lang.Object} object.
216 * @param status
217 * a {@link org.eclipse.core.runtime.IStatus} object.
218 */
219 public static void errorDialog(final String title,
220 final Object source,
221 final String message,
222 final IStatus status,
223 final boolean showStackTrace) {
224 if(showStackTrace && status.getException() != null) {
225 errorDialog(title, source, status.getPlugin(), message, status.getException());
226 } else {
227 errorDialog(title, source, message, status);
228 }
229 }
230
231
232 /**
233 * Displays a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog}.
234 *
235 * @param title
236 * a {@link java.lang.String} object.
237 * @param source
238 * a {@link java.lang.Object} object.
239 * @param status
240 * a {@link org.eclipse.core.runtime.IStatus} object.
241 */
242 public static void errorDialog(final String title, final Object source,
243 final IStatus status) {
244 errorDialog(title, source, null, status);
245 }
246
247 /**
248 * Displays a dialog for an exception occurring in an operation.
249 *
250 * This will be either a {@link eu.etaxonomy.taxeditor.model.CdmErrorDialog} in case of a
251 * security runtime exception or a warning {@link org.eclipse.jface.dialogs.MessageDialog} in
252 * case of any other exception.
253 *
254 * @param title
255 * a {@link java.lang.String} object.
256 * @param source
257 * a {@link java.lang.Object} object.
258 * @param status
259 * a {@link org.eclipse.core.runtime.IStatus} object.
260 */
261 public static void operationDialog(final Object source,
262 final Exception ex,
263 final String operationlabel,
264 final String hint) {
265
266 Display.getDefault().asyncExec(new Runnable() {
267
268 @Override
269 public void run() {
270 MultiStatus info = null;
271 String title = null;
272
273 // FIXME cannot access TaxonomicEditorPlugin.PLUGIN_ID from here
274 // String PID = TaxonomicEditorPlugin.PLUGIN_ID;
275 String PID = "eu.etaxonomy.taxeditor.application";
276
277 // checking security exceptions for every operation
278 RuntimeException securityRuntimeException = SecurityExceptionUtils.findSecurityRuntimeException(ex);
279
280 // in case of a security exception it is a warning, else it is an error
281 if(securityRuntimeException != null){
282 title = "Your changes could not be saved!";
283 warningDialog(title, source, String.format("You are missing sufficient permissions for the operation \"%s\". %s", operationlabel, hint));
284 } else {
285 title = "Error executing operation";
286 errorDialog(title, source, String.format("An error occured while executing %s. %s", operationlabel, hint), PID, ex);
287
288 }
289
290
291 }
292 });
293 }
294
295
296
297
298 /**
299 * Displays a question {@link org.eclipse.jface.dialogs.MessageDialog}.
300 *
301 * @param title
302 * a {@link java.lang.String} object.
303 * @param message
304 * a {@link java.lang.String} object.
305 * @return a boolean.
306 */
307 public static boolean confirmDialog(String title, String message) {
308 return MessageDialog.openQuestion(AbstractUtility.getShell(), title, message);
309 }
310
311 /**
312 * Displays a message {@link org.eclipse.jface.dialogs.MessageDialog}.
313 *
314 * @param title
315 * @param source
316 * @param message
317 */
318 public static void messageDialog(final String title, final Object source, final String message) {
319 MessagingUtils.messageDialog(title, source, message, null);
320 }
321
322 /**
323 * Displays an error {@link org.eclipse.jface.dialogs.MessageDialog}.
324 *
325 * @param title
326 * The dialogs title
327 * @param source
328 * The object where the warning was generated (used by log4j)
329 * @param message
330 * An informative String to be presented to the user
331 * @param title
332 * The dialogs title
333 * @param t
334 * a Throwable if one exists or null
335 */
336 public static void messageDialog(final String title, final Object source,
337 final String message, final Throwable t) {
338 Display.getDefault().asyncExec(new Runnable() {
339
340 @Override
341 public void run() {
342 MessageDialog.openError(AbstractUtility.getShell(), title, message + getCauseRecursively(t));
343 Class<? extends Object> clazz = source != null ? source
344 .getClass() : this.getClass();
345 error(clazz, message, t);
346 }
347
348 private String getCauseRecursively(Throwable t) {
349 if(t == null){
350 return "";
351 }
352
353 if(t.getCause() != null){
354 return getCauseRecursively(t.getCause());
355 }else{
356 return String.format("\n\nException: %s\nMessage: %s", t.getClass().getSimpleName(), t.getMessage());
357 }
358
359 }
360 });
361 }
362
363 /**
364 * Displays a warning {@link org.eclipse.jface.dialogs.MessageDialog}.
365 *
366 * @param title
367 * @param termBase
368 * @param status
369 */
370 public static void warningDialog(String title, Object source,
371 IStatus status) {
372 MessagingUtils.warningDialog(title, source, status.getMessage());
373 }
374
375 /**
376 * Displays a warning {@link org.eclipse.jface.dialogs.MessageDialog}.
377 *
378 * @param title
379 * The dialogs title
380 * @param source
381 * The object where the warning was generated (used by log4j)
382 * @param message
383 * An informative String to be presented to the user
384 */
385 public static void warningDialog(final String title, final Object source, final String message) {
386 Display.getDefault().asyncExec(new Runnable() {
387
388 @Override
389 public void run() {
390 MessageDialog.openWarning(AbstractUtility.getShell(), title, message);
391 Class<? extends Object> clazz = source != null ? source
392 .getClass() : AbstractUtility.class;
393 warn(clazz, message);
394 }
395 });
396 }
397
398 /**
399 * Displays an information {@link org.eclipse.jface.dialogs.MessageDialog}.
400 *
401 * @param title
402 * @param status
403 */
404 public static void informationDialog(final String title, final IStatus status) {
405 MessagingUtils.informationDialog(title, status.getMessage());
406 }
407
408 /**
409 * Displays an information {@link org.eclipse.jface.dialogs.MessageDialog}.
410 *
411 * @param title
412 * a {@link java.lang.String} object.
413 * @param message
414 * a {@link java.lang.String} object.
415 */
416 public static void informationDialog(final String title,
417 final String message) {
418 Display.getDefault().asyncExec(new Runnable() {
419
420 @Override
421 public void run() {
422 MessageDialog.openInformation(AbstractUtility.getShell(), title, message);
423 }
424 });
425 }
426
427 /**
428 * Open a message box that informs the user about unimplemented
429 * functionality. This method is for developer convenience.
430 *
431 * @param source
432 * a {@link java.lang.Object} object.
433 */
434 public static void notImplementedMessage(Object source) {
435 warningDialog("Not yet implemented", source,
436 "This functionality is not yet implemented.");
437 }
438
439 }