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