blob: 0b62b04dddedbf5db925f1873ed489f9f9655312 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.breakpoints;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.debug.ui.InspectPopupDialog;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextManager;
import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaExceptionBreakpoint;
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.actions.PopupInspectAction;
import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
/**
* This class is used to show the inspect pop-up when a thread is suspended due to an exception being thrown
*/
public class ExceptionInspector implements IDebugContextListener, IPreferenceChangeListener {
/**
* Constructor
*/
public ExceptionInspector() {
IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(JDIDebugUIPlugin.getUniqueIdentifier());
if(prefs != null) {
prefs.addPreferenceChangeListener(this);
}
boolean doit = Platform.getPreferencesService().getBoolean(
JDIDebugUIPlugin.getUniqueIdentifier(),
IJDIPreferencesConstants.PREF_OPEN_INSPECT_POPUP_ON_EXCEPTION,
false,
null);
if (doit) {
DebugUITools.getDebugContextManager().addDebugContextListener(this);
}
}
/**
* @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent)
*/
@Override
public void debugContextChanged(DebugContextEvent event) {
if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
IWorkbenchPart part = event.getDebugContextProvider().getPart();
if (part != null) {
IWorkbenchPartSite site = part.getSite();
if (site != null && IDebugUIConstants.ID_DEBUG_VIEW.equals(site.getId())) {
IWorkbenchPage page = site.getWorkbenchWindow().getActivePage();
if (page != null && page.isPartVisible(part)) {
ISelection selection = event.getContext();
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
if (ss.size() == 1) {
Object firstElement = ss.getFirstElement();
if (firstElement instanceof IAdaptable) {
IJavaStackFrame frame = ((IAdaptable) firstElement).getAdapter(IJavaStackFrame.class);
if (frame != null) {
IJavaThread thread = (IJavaThread)frame.getThread();
try {
if (frame.equals(thread.getTopStackFrame())) {
IBreakpoint[] breakpoints = thread.getBreakpoints();
if (breakpoints.length == 1) {
if (breakpoints[0] instanceof IJavaExceptionBreakpoint) {
IJavaExceptionBreakpoint exception = (IJavaExceptionBreakpoint) breakpoints[0];
IJavaObject lastException = ((JavaExceptionBreakpoint)exception).getLastException();
if (lastException != null) {
IExpression exp = new JavaInspectExpression(exception.getExceptionTypeName(), lastException);
Tree tree = (Tree) ((IDebugView)part).getViewer().getControl();
TreeItem[] selection2 = tree.getSelection();
Rectangle bounds = selection2[0].getBounds();
Point point = tree.toDisplay(bounds.x, bounds.y + bounds.height);
InspectPopupDialog dialog = new InspectPopupDialog(part.getSite().getShell(),
point, PopupInspectAction.ACTION_DEFININITION_ID, exp);
dialog.open();
}
}
}
}
} catch (DebugException e) {}
}
}
}
}
}
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent)
*/
@Override
public void preferenceChange(PreferenceChangeEvent event) {
if (IJDIPreferencesConstants.PREF_OPEN_INSPECT_POPUP_ON_EXCEPTION.equals(event.getKey())) {
IDebugContextManager manager = DebugUITools.getDebugContextManager();
boolean doit = Platform.getPreferencesService().getBoolean(
JDIDebugUIPlugin.getUniqueIdentifier(),
IJDIPreferencesConstants.PREF_OPEN_INSPECT_POPUP_ON_EXCEPTION,
false,
null);
if (doit) {
manager.addDebugContextListener(this);
} else {
manager.removeDebugContextListener(this);
}
}
}
}