org.eclipse.gmf.internal.codegen.popup.actions.DiagnosticsDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.gmf.internal.codegen.popup.actions.DiagnosticsDialog.java

Source

/*
 * Copyright (c) 2006 Borland Software Corp
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *  
 * Contributors: dvorak - initial API and implementation
 */
package org.eclipse.gmf.internal.codegen.popup.actions;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.gmf.internal.bridge.transform.ValidationHelper;
import org.eclipse.gmf.internal.bridge.transform.ValidationHelper.DiagnosticMarkerMap;
import org.eclipse.gmf.internal.codegen.CodeGenUIPlugin;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IconAndMessageDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
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.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.part.FileEditorInput;

/**
 * A dialog to display one or more errors to the user, as contained in an
 * <code>Diagnostic</code> object. If an error contains additional detailed
 * information then a Details button is automatically supplied, which shows or
 * hides an error details viewer when pressed by the user.<p>  
 * 
 * @see org.eclipse.emf.common.util.Diagnostic
 */
@SuppressWarnings("synthetic-access")
public class DiagnosticsDialog extends IconAndMessageDialog {

    private static class DiagnosticLabelProvider extends LabelProvider {
        @Override
        public Image getImage(Object element) {
            if (!(element instanceof Diagnostic)) {
                return null;
            }
            Diagnostic diagnostic = (Diagnostic) element;
            String imageName = ISharedImages.IMG_OBJS_ERROR_TSK;
            switch (diagnostic.getSeverity()) {
            case Diagnostic.INFO:
                imageName = ISharedImages.IMG_OBJS_INFO_TSK;
                break;
            case Diagnostic.WARNING:
                imageName = ISharedImages.IMG_OBJS_WARN_TSK;
                break;
            }
            return PlatformUI.getWorkbench().getSharedImages().getImage(imageName);
        }

        @Override
        public String getText(Object element) {
            if (element instanceof Diagnostic) {
                Diagnostic diagnostic = (Diagnostic) element;
                if (diagnostic.getMessage() != null) {
                    return diagnostic.getMessage();
                }
            }
            return super.getText(element);
        }
    }

    private static class DiagnosticContentProvider implements ITreeContentProvider {

        Object cachedInput;
        boolean showTopLevel;

        DiagnosticContentProvider(boolean showTopLevelDiagnostic) {
            showTopLevel = showTopLevelDiagnostic;
        }

        public Object[] getChildren(Object parentElement) {
            if (parentElement instanceof Diagnostic) {
                Diagnostic diagnostic = (Diagnostic) parentElement;
                return diagnostic.getChildren().toArray();
            }
            return new Object[0];
        }

        public Object getParent(Object element) {
            return null;
        }

        public boolean hasChildren(Object element) {
            if (element instanceof Diagnostic) {
                Diagnostic diagnostic = (Diagnostic) element;
                return !diagnostic.getChildren().isEmpty();
            }
            return false;
        }

        public Object[] getElements(Object inputElement) {
            if (inputElement instanceof Diagnostic) {
                Diagnostic diagnostic = (Diagnostic) inputElement;
                if (diagnostic == cachedInput && showTopLevel) {
                    cachedInput = null;
                    return new Object[] { diagnostic };
                }
                return diagnostic.getChildren().toArray();
            }
            return new Object[0];
        }

        public void dispose() {
            // do nothing here
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            cachedInput = newInput;
        }
    }

    /**
      * Reserve room for this many diagnosticTree items.
      */
    private static final int ITEM_COUNT = 7;

    private static final int STACK_TRACE_TEXT_LINE_COUNT = 3;

    /**
     * The nesting indent.
     */
    private static final String NESTING_INDENT = "  "; //$NON-NLS-1$

    /**
     * The Details button.
     */
    private Button detailsButton;

    /**
     * The title of the dialog.
     */
    private String title;

    /**
     * The SWT diagnosticTree control that displays the error details.
     */
    private TreeViewer diagnosticTree;

    /**
     * The SWT Text control that displays the error exception stack trace.
     */
    private Text stackTraceText;

    /**
     * Indicates whether the error details viewer is currently created.
     */
    private boolean detailsCreated = false;

    /**
     * The main rootDiagnotic object.
     */
    private Diagnostic rootDiagnotic;

    /**
     * The current clipboard. To be disposed when closing the dialog.
     */
    private Clipboard clipboard;

    private boolean shouldIncludeTopLevelErrorInDetails;

    private final String[] buttonLabels;

    private final int[] buttonIDs;

    private final int defaultButtonIndex;

    /**
     * Creates an diagnostic dialog. Note that the dialog will have no visual
     * representation (no widgets) until it is told to open.
     * <p>
     * 
     * @param parentShell
     *            the shell under which to create this dialog
     * @param dialogTitle
     *            the title to use for this dialog, or <code>null</code> to
     *            indicate that the default title should be used
     * @param dialogMessage
     *            the message to show in this dialog, or <code>null</code> to
     *            indicate that the error's message should be shown as the
     *            primary message
     * @param diagnostic
     *            the diagnostic grouping all errors to be shown to the user
     * @param dialogButtonLabels array of labels for buttons to create in the dialog button bar
     * @param dialogButtonIDs array of IDs for buttons to create in the dialog button bar
     * @param defaultDialogButtonIndex the index of the default button
     */
    public DiagnosticsDialog(Shell parentShell, String dialogTitle, String dialogMessage, Diagnostic diagnostic,
            String[] dialogButtonLabels, int[] dialogButtonIDs, int defaultDialogButtonIndex) {
        super(parentShell);

        if (diagnostic == null) {
            throw new IllegalArgumentException("Null diagnostic"); //$NON-NLS-1$
        }

        this.title = (dialogTitle == null) ? JFaceResources.getString("Problem_Occurred") : dialogTitle; //$NON-NLS-1$
        this.message = (dialogMessage == null) ? diagnostic.getMessage()
                : JFaceResources.format("Reason", new Object[] { dialogMessage, diagnostic.getMessage() }); //$NON-NLS-1$;

        this.rootDiagnotic = diagnostic;
        this.shouldIncludeTopLevelErrorInDetails = true;

        assert dialogButtonIDs != null && dialogButtonLabels != null;
        assert dialogButtonIDs.length == dialogButtonLabels.length;
        assert defaultDialogButtonIndex >= 0 && defaultDialogButtonIndex < dialogButtonIDs.length;

        buttonIDs = dialogButtonIDs;
        buttonLabels = dialogButtonLabels;
        defaultButtonIndex = defaultDialogButtonIndex;

        setShellStyle(getShellStyle() | SWT.RESIZE);
    }

    @Override
    protected void buttonPressed(int id) {
        if (id == IDialogConstants.DETAILS_ID) {
            // was the details button pressed?
            toggleDetailsArea();
        } else if (id == IDialogConstants.OK_ID || id == IDialogConstants.CANCEL_ID) {
            super.buttonPressed(id);
        } else {
            setReturnCode(id);
            close();
        }
    }

    @Override
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText(title);
    }

    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        for (int i = 0; i < buttonLabels.length; i++) {
            createButton(parent, buttonIDs[i], buttonLabels[i], defaultButtonIndex == i);
        }
        createDetailsButton(parent);
    }

    protected void createDetailsButton(Composite parent) {
        if (shouldShowDetailsButton()) {
            detailsButton = createButton(parent, IDialogConstants.DETAILS_ID, IDialogConstants.SHOW_DETAILS_LABEL,
                    false);
        }
    }

    /**
     * This implementation of the <code>Dialog</code> framework method creates
     * and lays out a composite and calls <code>createMessageArea</code> and
     * <code>createCustomArea</code> to populate it. Subclasses should
     * override <code>createCustomArea</code> to add contents below the
     * message.
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        createMessageArea(parent);
        // create a composite with standard margins and spacing
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        layout.numColumns = 2;
        composite.setLayout(layout);
        GridData childData = new GridData(GridData.FILL_BOTH);
        childData.horizontalSpan = 2;
        composite.setLayoutData(childData);
        composite.setFont(parent.getFont());
        return composite;
    }

    @Override
    protected void createDialogAndButtonArea(Composite parent) {
        super.createDialogAndButtonArea(parent);
        if (this.dialogArea instanceof Composite) {
            //Create a label if there are no children to force a smaller layout
            Composite dialogComposite = (Composite) dialogArea;
            if (dialogComposite.getChildren().length == 0) {
                new Label(dialogComposite, SWT.NULL);
            }
        }
    }

    @Override
    protected Image getImage() {
        if (rootDiagnotic != null) {
            if (rootDiagnotic.getSeverity() == Diagnostic.WARNING) {
                return getWarningImage();
            }
            if (rootDiagnotic.getSeverity() == Diagnostic.INFO) {
                return getInfoImage();
            }
        }
        return getErrorImage();
    }

    /**
     * Create this dialog's drop-down diagnosticTree component.
     * 
     * @param parent
     *            the parent composite
     * @return the drop-down diagnosticTree component
     */
    protected void createDropDownTree(Composite parent) {
        // create the diagnosticTree
        diagnosticTree = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL
                | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL);
        data.heightHint = diagnosticTree.getTree().getItemHeight() * ITEM_COUNT;
        data.horizontalSpan = 2;

        diagnosticTree.getTree().setLayoutData(data);
        diagnosticTree.getTree().setFont(parent.getFont());
        Menu copyMenu = createDiagnosticTreeMenu();

        diagnosticTree.getTree().setMenu(copyMenu);

        diagnosticTree.setLabelProvider(new DiagnosticLabelProvider());
        diagnosticTree.setContentProvider(new DiagnosticContentProvider(shouldIncludeTopLevelErrorInDetails));
        diagnosticTree.setInput(rootDiagnotic);

        diagnosticTree.expandToLevel(2);
        diagnosticTree.setSelection(new StructuredSelection(rootDiagnotic), true);
        diagnosticTree.getTree().setFocus();
    }

    /**
     * Opens an dialog to display the given diagnostic and proceed, cancel buttons.
     * <p>
     * 
     * @param parentShell
     *            the parent shell of the dialog, or <code>null</code> if none
     * @param title
     *            the title to use for this dialog, or <code>null</code> to
     *            indicate that the default title should be used
     * @param message
     *            the message to show in this dialog, or <code>null</code> to
     *            indicate that the error's message should be shown as the
     *            primary message
     * @param rootDiagnotic
     *            the diagnostic to show to the user
     *            
     * @return the code of the button that was pressed that resulted in this
     *         dialog closing. This will be <code>Dialog.OK</code> if the OK
     *         or <code>Dialog.CANCEL</code> if this dialog's close window decoration 
     *         or the ESC key was used.         
     */
    public static int openProceedCancel(Shell parentShell, String title, String message,
            Diagnostic rootDiagnostic) {
        return openProceedCancel(parentShell, title, message, rootDiagnostic, false);
    }

    /**
    * Opens an dialog to display the given diagnostic and proceed, cancel
    * buttons.
    * <p>
    * 
    * @param parentShell
    *            the parent shell of the dialog, or <code>null</code> if none
    * @param title
    *            the title to use for this dialog, or <code>null</code> to
    *            indicate that the default title should be used
    * @param message
    *            the message to show in this dialog, or <code>null</code> to
    *            indicate that the error's message should be shown as the
    *            primary message
    * @param rootDiagnotic
    *            the diagnostic to show to the user
    * 
    * @param disableProceed
    *            indicates whether the <code>PROCEED</code> button should be
    *            disabled.
    * @return the code of the button that was pressed that resulted in this
    *         dialog closing. This will be <code>Dialog.OK</code> if the OK
    *         or <code>Dialog.CANCEL</code> if this dialog's close window
    *         decoration or the ESC key was used.
    */
    public static int openProceedCancel(Shell parentShell, String title, String message, Diagnostic rootDiagnostic,
            final boolean disableProceed) {
        DiagnosticsDialog dialog = new DiagnosticsDialog(parentShell, title, message, rootDiagnostic,
                new String[] { IDialogConstants.PROCEED_LABEL, IDialogConstants.CANCEL_LABEL },
                new int[] { IDialogConstants.PROCEED_ID, IDialogConstants.CANCEL_ID }, 0) {
            @Override
            protected Control createButtonBar(Composite parent) {
                Control buttonBar = super.createButtonBar(parent);
                Button proceedButton = getButton(IDialogConstants.PROCEED_ID);
                if (proceedButton != null) {
                    proceedButton.setEnabled(!disableProceed);
                }
                return buttonBar;
            }
        };
        return dialog.open();
    }

    /**
    * Opens an dialog to display the given diagnostic and <code>OK</code> button.
    * <p>
    * 
    * @param parentShell
    *            the parent shell of the dialog, or <code>null</code> if none
    * @param title
    *            the title to use for this dialog, or <code>null</code> to
    *            indicate that the default title should be used
    * @param message
    *            the message to show in this dialog, or <code>null</code> to
    *            indicate that the error's message should be shown as the
    *            primary message
    * @param rootDiagnotic
    *            the diagnostic to show to the user
    *
    * @return the code of the button that was pressed that resulted in this
    *         dialog closing. This will be <code>Dialog.OK</code> if the OK
    *         or <code>Dialog.CANCEL</code> if this dialog's close window
    *         decoration or the ESC key was used.
    */
    public static int openOk(Shell parentShell, String title, String message, Diagnostic rootDiagnostic) {
        return new DiagnosticsDialog(parentShell, title, message, rootDiagnostic,
                new String[] { IDialogConstants.OK_LABEL }, new int[] { IDialogConstants.OK_ID }, 0).open();
    }

    private Object getSelection() {
        if (diagnosticTree != null && !diagnosticTree.getTree().isDisposed()) {
            ISelection selection = diagnosticTree.getSelection();
            if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
                IStructuredSelection structuredSelection = (IStructuredSelection) selection;
                return structuredSelection.getFirstElement();
            }
        }
        return null;
    }

    private Diagnostic getDiagnosticSelection() {
        Object selection = getSelection();
        return selection instanceof Diagnostic ? (Diagnostic) selection : null;
    }

    /**
     * Toggles the unfolding of the details area. This is triggered by the user
     * pressing the details button.
     */
    private void toggleDetailsArea() {
        Point windowSize = getShell().getSize();
        Point oldSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
        if (detailsCreated) {
            diagnosticTree.getTree().dispose();
            stackTraceText.dispose();

            detailsCreated = false;
            detailsButton.setText(IDialogConstants.SHOW_DETAILS_LABEL);
        } else {
            createDetailsArea((Composite) getContents());

            detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL);
        }
        Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
        getShell().setSize(new Point(windowSize.x, windowSize.y + (newSize.y - oldSize.y)));
    }

    /**
     * Put the details of the rootDiagnotic of the error onto the stream.
     * 
     * @param buildingDiagnostic
     * @param buffer
     * @param nesting
     */
    private void populateCopyBuffer(Diagnostic buildingDiagnostic, StringBuffer buffer, int nesting) {

        for (int i = 0; i < nesting; i++) {
            buffer.append(NESTING_INDENT);
        }
        buffer.append(buildingDiagnostic.getMessage());
        buffer.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$

        // Look for a nested core exception
        Throwable t = buildingDiagnostic.getException();
        if (t instanceof CoreException) {
            CoreException ce = (CoreException) t;
            populateCopyBuffer(BasicDiagnostic.toDiagnostic(ce), buffer, nesting + 1);
        }

        List<Diagnostic> children = buildingDiagnostic.getChildren();
        for (Diagnostic next : children) {
            populateCopyBuffer(next, buffer, nesting + 1);
        }
    }

    public boolean close() {
        if (clipboard != null) {
            clipboard.dispose();
        }
        return super.close();
    }

    /**
     * Show the details portion of the dialog if it is not already visible.
     * This method will only work when it is invoked after the control of the dialog
     * has been set. In other words, after the <code>createContents</code> method
     * has been invoked and has returned the control for the content area of the dialog.
     * Invoking the method before the content area has been set or after the dialog has been
     * disposed will have no effect.
     * @since 3.1
     */
    protected final void showDetailsArea() {
        if (!detailsCreated) {
            Control control = getContents();
            if (control != null && !control.isDisposed()) {
                toggleDetailsArea();
            }
        }
    }

    /**
     * Return whether the Details button should be included.
     * This method is invoked once when the dialog is built.
     * By default, the Details button is only included if
     * the rootDiagnotic used when creating the dialog was a multi-rootDiagnotic
     * or if the rootDiagnotic contains an exception.
     * Subclasses may override.
     * @return whether the Details button should be included
     */
    protected boolean shouldShowDetailsButton() {
        return !rootDiagnotic.getChildren().isEmpty() || rootDiagnotic.getException() != null;
    }

    private void createDetailsArea(Composite parent) {
        createDropDownTree(parent);
        createDropDownText(parent, diagnosticTree.getTree().getBackground());

        this.diagnosticTree.addPostSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                Throwable throwable = getExceptionSelection();
                String textValue = ""; //$NON-NLS-1$
                if (throwable != null) {
                    // print the stacktrace in the stackTraceText field
                    try {
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        PrintStream ps = new PrintStream(baos);
                        throwable.printStackTrace(ps);
                        ps.flush();
                        baos.flush();
                        textValue = baos.toString();
                    } catch (IOException e) {
                        // no reason for IO error
                    }
                }

                stackTraceText.setText(textValue);
            }
        });

        this.detailsCreated = true;
    }

    private void createDropDownText(Composite parent, Color backgroundColor) {
        // create the list
        stackTraceText = new Text(parent, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL);
        stackTraceText.setBackground(backgroundColor);
        stackTraceText.setFont(parent.getFont());

        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL
                | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL);
        data.heightHint = stackTraceText.getLineHeight() * STACK_TRACE_TEXT_LINE_COUNT;
        data.horizontalSpan = 2;
        stackTraceText.setLayoutData(data);

        stackTraceText.setToolTipText(Messages.DiagnosticsDialog_exceptStackTrace_toolTip);
    }

    private Menu createDiagnosticTreeMenu() {
        Menu diagnosticMenu = new Menu(diagnosticTree.getTree());
        MenuItem copyItem = new MenuItem(diagnosticMenu, SWT.NONE);
        copyItem.setText(Messages.DiagnosticsDialog_Copy_menuItem);
        copyItem.addSelectionListener(new SelectionListener() {
            public void widgetSelected(SelectionEvent e) {
                copyToClipboard();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
                copyToClipboard();
            }
        });

        if (ValidationHelper.getDiagnosticMarkerMap(rootDiagnotic) != null) {
            MenuItem gotoItem = new MenuItem(diagnosticMenu, SWT.NONE);
            gotoItem.setText(Messages.DiagnosticsDialog_gotoProblem_menuItem);
            gotoItem.addSelectionListener(new SelectionListener() {
                public void widgetSelected(SelectionEvent e) {
                    gotoProblem();
                }

                public void widgetDefaultSelected(SelectionEvent e) {
                    gotoProblem();
                }
            });
        }

        return diagnosticMenu;
    }

    /**
     * Copy the contents of the statuses to the clipboard.
     */
    private void copyToClipboard() {
        if (clipboard != null) {
            clipboard.dispose();
        }
        StringBuffer statusBuffer = new StringBuffer();
        Diagnostic source = getDiagnosticSelection();
        populateCopyBuffer((source != null) ? source : rootDiagnotic, statusBuffer, 0);
        clipboard = new Clipboard(getShell().getDisplay());

        clipboard.setContents(new Object[] { statusBuffer.toString() },
                new Transfer[] { TextTransfer.getInstance() });
    }

    private void gotoProblem() {
        Diagnostic diagnostic = getDiagnosticSelection();
        if (diagnostic == null) {
            return;
        }

        DiagnosticMarkerMap markerMap = ValidationHelper.getDiagnosticMarkerMap(rootDiagnotic);
        IMarker marker = null;
        if (markerMap != null) {
            if (!markerMap.getMap().containsKey(diagnostic) && diagnostic == rootDiagnotic
                    && !diagnostic.getChildren().isEmpty()) {
                // the root is usually just a wrapper containing real diagnostics with markers 
                // -> take the first one
                diagnostic = diagnostic.getChildren().get(0);
            }
            marker = markerMap.getMap().get(diagnostic);
        }

        IWorkbench workbench = PlatformUI.getWorkbench();
        IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
        IWorkbenchPage page = (workbenchWindow != null) ? workbenchWindow.getActivePage() : null;
        if (page == null) {
            return;
        }

        try {
            // activate the problem view to         
            page.showView("org.eclipse.ui.views.ProblemView"); //$NON-NLS-1$
        } catch (PartInitException e) {
            CodeGenUIPlugin.getDefault().getLog().log(e.getStatus());
        }

        IFile file = ValidationHelper.getFileFromDiagnostic(diagnostic);
        if (file != null) {
            try {
                String editorId = "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$            
                IEditorPart editorPart = null;
                if (marker == null || marker.getAttribute(EValidator.URI_ATTRIBUTE, null) != null) {
                    IEditorDescriptor[] editorDescriptors = PlatformUI.getWorkbench().getEditorRegistry()
                            .getEditors(file.getName());
                    if (editorDescriptors.length > 0) {
                        editorId = editorDescriptors[0].getId();
                    }
                }

                editorPart = page.openEditor(new FileEditorInput(file), editorId, true,
                        IWorkbenchPage.MATCH_INPUT | IWorkbenchPage.MATCH_ID);
                IGotoMarker gotoMarkerSupport = null;
                if (editorPart != null) {
                    gotoMarkerSupport = (IGotoMarker) editorPart.getAdapter(IGotoMarker.class);
                    cancelPressed();
                }

                if (gotoMarkerSupport != null && marker != null) {
                    // delegate to goto marker of the activated editor
                    gotoMarkerSupport.gotoMarker(marker);
                }

            } catch (PartInitException e) {
                CodeGenUIPlugin.getDefault().getLog().log(e.getStatus());
            }
        }
    }

    private Throwable getExceptionSelection() {
        Diagnostic selection = getDiagnosticSelection();
        return (selection != null) ? selection.getException() : null;
    }

    static Diagnostic toDiagnostic(IStatus status) {
        Object[] data = null;
        if (status.getException() != null) {
            data = new Object[] { status.getException() };
        }

        if (status.isMultiStatus()) {
            IStatus[] nestedStatuses = status.getChildren();
            List<Diagnostic> children = new ArrayList<Diagnostic>(nestedStatuses.length);
            for (int i = 0; i < nestedStatuses.length; i++) {
                children.add(toDiagnostic(nestedStatuses[i]));
            }
            return new BasicDiagnostic(status.getPlugin(), status.getCode(), children, status.getMessage(), data);
        }
        return new BasicDiagnostic(status.getSeverity(), status.getPlugin(), status.getCode(), status.getMessage(),
                data);
    }
}