eu.esdihumboldt.hale.ui.util.dialog.StackTraceErrorDialog.java Source code

Java tutorial

Introduction

Here is the source code for eu.esdihumboldt.hale.ui.util.dialog.StackTraceErrorDialog.java

Source

/*
 * 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;
    }
}