package rocks.inspectit.ui.rcp.statushandlers; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.statushandlers.StatusAdapter; import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.ui.statushandlers.WorkbenchErrorHandler; import rocks.inspectit.shared.all.exception.BusinessException; import rocks.inspectit.ui.rcp.dialog.BusinessExceptionDialog; import rocks.inspectit.ui.rcp.dialog.ThrowableDialog; /** * Custom status manager for displaying statuses and exceptions correctly. * * @author Ivan Senic * */ @SuppressWarnings("restriction") public class CustomStatusHandler extends WorkbenchErrorHandler { /** * {@inheritDoc} */ @Override public void handle(final StatusAdapter statusAdapter, int style) { // if style is only log and we have an error // then we want to show it as well to the user if ((StatusManager.LOG == style) && (statusAdapter.getStatus().getSeverity() == IStatus.ERROR)) { style |= StatusManager.SHOW; } // here we only show new type if it's error or warning with exception in if ((statusAdapter.getStatus().getException() != null) && ((statusAdapter.getStatus().getSeverity() == IStatus.WARNING) || (statusAdapter.getStatus().getSeverity() == IStatus.ERROR))) { if (((style & StatusManager.SHOW) == StatusManager.SHOW) || ((style & StatusManager.BLOCK) == StatusManager.BLOCK)) { if (Display.getCurrent() != null) { showErrorDialog(statusAdapter); } else { Display.getDefault().syncExec(new Runnable() { @Override public void run() { showErrorDialog(statusAdapter); } }); } } if ((style & StatusManager.LOG) == StatusManager.LOG) { StatusManager.getManager().addLoggedStatus(statusAdapter.getStatus()); WorkbenchPlugin.getDefault().getLog().log(statusAdapter.getStatus()); } } else { super.handle(statusAdapter, style); } } /** * Shows new style of error dialogs. * * @param statusAdapter * {@link StatusAdapter} */ protected void showErrorDialog(StatusAdapter statusAdapter) { if (ignore(statusAdapter.getStatus())) { return; } if (!PlatformUI.isWorkbenchRunning()) { // we are shutting down, so just log WorkbenchPlugin.log(statusAdapter.getStatus()); return; } Dialog dialog = null; if (statusAdapter.getStatus().getException() instanceof BusinessException) { dialog = new BusinessExceptionDialog(null, (BusinessException) statusAdapter.getStatus().getException()); } else { String message = statusAdapter.getStatus().getMessage(); if (StringUtils.isEmpty(message)) { message = statusAdapter.getStatus().getException().getMessage(); } dialog = new ThrowableDialog(null, message, statusAdapter.getStatus().getException()); } dialog.open(); } /** * If status should be ignored for showing the the error dialog. * <P> * Currently we ignore statuses with following exceptions: * <ul> * <li>NullPointerException on MacOSx in the * {@link org.eclipse.swt.widgets.Control#internal_new_GC(org.eclipse.swt.graphics.GCData)} * method as it's known SWT bug. * </ul> * * @param status * status to check * @return true if this status should be ignored */ private boolean ignore(IStatus status) { Throwable exception = status.getException(); if ((exception instanceof NullPointerException) && SystemUtils.IS_OS_MAC_OSX) { StackTraceElement[] stackTrace = exception.getStackTrace(); if (ArrayUtils.isNotEmpty(stackTrace)) { StackTraceElement topElement = stackTrace[0]; if ("org.eclipse.swt.widgets.Control".equals(topElement.getClassName()) && "internal_new_GC".equals(topElement.getMethodName())) { return true; } } } return false; } }