blob: 36a5dda9b11f2806614ba0d0dad7844023984d34 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.actions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.internal.ui.AbstractDebugCheckboxSelectionDialog;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
import org.eclipse.jdt.debug.core.IJavaFieldVariable;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
/**
* Action to associate an object with one or more breakpoints.
*/
public class InstanceFiltersAction extends ObjectActionDelegate {
/**
* Dialog that allows the user to select one or more breakpoints that should be restricted
* to a specific object instance.
*/
class InstanceFilterDialog extends AbstractDebugCheckboxSelectionDialog {
private Object fInput;
private String fMessage;
private IBaseLabelProvider fLabelProvider;
public InstanceFilterDialog(Shell parentShell, Object input, IBaseLabelProvider labelProvider, String message){
super(parentShell);
fInput = input;
fMessage = message;
fLabelProvider = labelProvider;
setShellStyle(getShellStyle() | SWT.RESIZE);
setShowSelectAllButtons(true);
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.AbstractDebugCheckboxSelectionDialog#isValid()
*/
@Override
protected boolean isValid() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getDialogSettingsId()
*/
@Override
protected String getDialogSettingsId() {
return IJavaDebugUIConstants.PLUGIN_ID + ".INSTANCE_FILTERS_ACTION_DIALOG"; //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getHelpContextId()
*/
@Override
protected String getHelpContextId() {
return IJavaDebugHelpContextIds.INSTANCE_BREAKPOINT_SELECTION_DIALOG;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getViewerInput()
*/
@Override
protected Object getViewerInput() {
return fInput;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getViewerLabel()
*/
@Override
protected String getViewerLabel() {
return fMessage;
}
/* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractDebugSelectionDialog#getLabelProvider()
*/
@Override
protected IBaseLabelProvider getLabelProvider() {
return fLabelProvider;
}
}
/**
* @see org.eclipse.ui.IActionDelegate#run(IAction)
*/
@Override
public void run(IAction action) {
IStructuredSelection selection = getCurrentSelection();
if (selection == null || selection.size() > 1) {
return;
}
Object o = selection.getFirstElement();
if (o instanceof IJavaVariable) {
final IJavaVariable var = (IJavaVariable)o;
try {
IValue value = var.getValue();
if (value instanceof IJavaObject) {
final IJavaObject object = (IJavaObject)value;
final List<IJavaBreakpoint> breakpoints = getApplicableBreakpoints(var, object);
final IDebugModelPresentation modelPresentation= DebugUITools.newDebugModelPresentation();
if (breakpoints.isEmpty())
{
MessageDialog.openInformation(JDIDebugUIPlugin.getActiveWorkbenchShell(), ActionMessages.InstanceFiltersAction_0, ActionMessages.InstanceFiltersAction_4);
return;
}
InstanceFilterDialog dialog = new InstanceFilterDialog(JDIDebugUIPlugin.getActiveWorkbenchShell(), breakpoints, modelPresentation, NLS.bind(ActionMessages.InstanceFiltersAction_1, new String[] {var.getName()})){
@Override
public void okPressed() {
// check if breakpoints have already been restricted to other objects.
Object[] checkBreakpoint= getCheckBoxTableViewer().getCheckedElements();
for (int k= 0; k < checkBreakpoint.length; k++) {
IJavaBreakpoint breakpoint= (IJavaBreakpoint) checkBreakpoint[k];
try {
IJavaObject[] instanceFilters= breakpoint.getInstanceFilters();
boolean sameTarget = false;
for (int i = 0; i < instanceFilters.length; i++) {
IJavaObject instanceFilter = instanceFilters[i];
if (instanceFilter.getDebugTarget().equals(object.getDebugTarget())) {
sameTarget = true;
break;
}
}
if (sameTarget) {
MessageDialog messageDialog= new MessageDialog(JDIDebugUIPlugin.getActiveWorkbenchShell(), ActionMessages.InstanceFiltersAction_2,
null, NLS.bind(ActionMessages.InstanceFiltersAction_3, new String[] { modelPresentation.getText(breakpoint), var.getName()}),
MessageDialog.QUESTION, new String[] { ActionMessages.InstanceFiltersAction_Yes_2, ActionMessages.InstanceFiltersAction_Cancel_3}, //
0);
if (messageDialog.open() == Window.OK) {
for (int i= 0; i < instanceFilters.length; i++) {
breakpoint.removeInstanceFilter(instanceFilters[i]);
}
} else {
// if 'cancel', do not close the instance filter dialog
return;
}
}
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
}
super.okPressed();
}
};
dialog.setTitle(ActionMessages.InstanceFiltersAction_2);
// determine initial selection
List<IJavaBreakpoint> existing = new ArrayList<>();
Iterator<IJavaBreakpoint> iter = breakpoints.iterator();
while (iter.hasNext()) {
IJavaBreakpoint bp = iter.next();
IJavaObject[] filters = bp.getInstanceFilters();
for (int i = 0; i < filters.length; i++) {
if (filters[i].equals(object)) {
existing.add(bp);
break;
}
}
}
dialog.setInitialSelections(existing.toArray());
if (dialog.open() == Window.OK) {
Object[] selectedBreakpoints = dialog.getResult();
if (selectedBreakpoints != null) {
// add
for (int i = 0; i < selectedBreakpoints.length; i++) {
IJavaBreakpoint bp = (IJavaBreakpoint)selectedBreakpoints[i];
bp.addInstanceFilter(object);
existing.remove(bp);
}
// remove
iter = existing.iterator();
while (iter.hasNext()) {
IJavaBreakpoint bp = iter.next();
bp.removeInstanceFilter(object);
}
}
}
} else {
// only allowed for objects
}
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
}
}
protected List<IJavaBreakpoint> getApplicableBreakpoints(IJavaVariable variable, IJavaObject object) {
List<IJavaBreakpoint> breakpoints = new ArrayList<>();
try {
// collect names in type hierarchy
List<String> superTypeNames = new ArrayList<>();
IJavaType type = object.getJavaType();
while (type instanceof IJavaClassType) {
superTypeNames.add(type.getName());
type = ((IJavaClassType)type).getSuperclass();
}
IBreakpoint[] allBreakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
for (int i = 0; i < allBreakpoints.length; i++) {
if (allBreakpoints[i] instanceof IJavaBreakpoint) {
IJavaBreakpoint jbp = (IJavaBreakpoint)allBreakpoints[i];
IJavaBreakpoint valid = null;
if (jbp instanceof IJavaWatchpoint && variable instanceof IJavaFieldVariable) {
IJavaWatchpoint wp = (IJavaWatchpoint)jbp;
IJavaFieldVariable fv = (IJavaFieldVariable)variable;
if (variable.getName().equals(wp.getFieldName()) && fv.getDeclaringType().getName().equals(wp.getTypeName())) {
valid = wp;
}
} else if (superTypeNames.contains(jbp.getTypeName()) || jbp instanceof IJavaExceptionBreakpoint) {
valid = jbp;
}
if (valid != null && valid.supportsInstanceFilters()) {
breakpoints.add(valid);
}
}
}
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
return breakpoints;
}
}