/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * HUMBOLDT EU Integrated Project #030962 * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.ui.util.dialog; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.internal.Workbench; import org.eclipse.ui.internal.WorkbenchMessages; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.statushandlers.StatusManager; /** * Extended ErrorDialog which displays the stack trace. Can be configured to * also show a link to the error log view. * * @author Michel Kraemer * @author Simon Templer */ @SuppressWarnings("restriction") public class StackTraceErrorDialog extends ErrorDialog { /** * ID of the Error Log view */ protected static final String LOG_VIEW_ID = "org.eclipse.pde.runtime.LogView"; //$NON-NLS-1$ /** * The status that should be shown */ private IStatus _status; /** * The current clipboard */ private Clipboard _clipboard; /** * The list that shows the stack trace */ private List _list; /** * If the error log link shall be shown */ private boolean showErrorLogLink = false; /** * Constructs a new error dialog * * @see ErrorDialog#ErrorDialog(Shell, String, String, IStatus, int) */ public StackTraceErrorDialog(Shell parentShell, String dialogTitle, String message, IStatus status, int displayMask) { super(parentShell, dialogTitle, message, status, displayMask); _status = status; } /** * @param showErrorLogLink if the error log link shall be shown */ public void setShowErrorLogLink(boolean showErrorLogLink) { this.showErrorLogLink = showErrorLogLink; } /** * @see ErrorDialog#createDropDownList(Composite) */ @Override protected List createDropDownList(Composite parent) { _list = super.createDropDownList(parent); _list.removeAll(); // replace context menu _list.getMenu().dispose(); Menu copyMenu = new Menu(_list); MenuItem copyItem = new MenuItem(copyMenu, SWT.NONE); copyItem.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent e) { copyToClipboard(); } @Override public void widgetSelected(SelectionEvent e) { copyToClipboard(); } }); copyItem.setText(JFaceResources.getString("copy")); //$NON-NLS-1$ _list.setMenu(copyMenu); // convert stack trace to string String stackTrace = stackTraceToString(_status.getException()); if (stackTrace != null) { // add stack trace to list stackTrace = stackTrace.replaceAll("\r", ""); //$NON-NLS-1$ //$NON-NLS-2$ stackTrace = stackTrace.replaceAll("\t", " "); //$NON-NLS-1$ //$NON-NLS-2$ String[] lines = stackTrace.split("\n"); //$NON-NLS-1$ for (String l : lines) { _list.add(l); } } return _list; } /** * Creates a string from a stack trace * * @param t the exception * @return the stack trace as a string */ private String stackTraceToString(Throwable t) { if (t == null) { return null; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintWriter pw = new PrintWriter(baos); _status.getException().printStackTrace(pw); pw.flush(); return baos.toString(); } /** * Copies the stack trace to the clipboard */ protected void copyToClipboard() { if (_clipboard != null) { _clipboard.dispose(); } String stackTrace = stackTraceToString(_status.getException()); _clipboard = new Clipboard(_list.getDisplay()); _clipboard.setContents(new Object[] { stackTrace }, new Transfer[] { TextTransfer.getInstance() }); } private Link createShowErrorLogLink(Composite parent) { Link link = new Link(parent, SWT.NONE); link.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { try { Workbench.getInstance().getActiveWorkbenchWindow().getActivePage() .showView(LOG_VIEW_ID); } catch (CoreException ce) { StatusManager.getManager().handle(ce, WorkbenchPlugin.PI_WORKBENCH); } } }); link.setText(WorkbenchMessages.ErrorLogUtil_ShowErrorLogHyperlink); link.setToolTipText(WorkbenchMessages.ErrorLogUtil_ShowErrorLogTooltip); Dialog.applyDialogFont(link); return link; } /** * @see ErrorDialog#close() */ @Override public boolean close() { if (_clipboard != null) { _clipboard.dispose(); _clipboard = null; } return super.close(); } /** * @see ErrorDialog#createDialogArea(Composite) */ @Override protected Control createDialogArea(Composite parent) { Composite main = (Composite) super.createDialogArea(parent); if (shouldDisplayLinkToErrorLog()) { Composite space = new Composite(main, SWT.NONE); GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); gridData.heightHint = 1; gridData.widthHint = 1; space.setLayoutData(gridData); Link link = createShowErrorLogLink(main); link.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); } return main; } private boolean shouldDisplayLinkToErrorLog() { /* no support for error log */ if (!showErrorLogLink) { return false; } /* view description */ return Workbench.getInstance().getViewRegistry().find(LOG_VIEW_ID) != null; } }