mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
xdebugger: added support for default breakpoints
This commit is contained in:
@@ -50,6 +50,8 @@ public interface XBreakpointManager {
|
||||
XLineBreakpoint<P> findBreakpointAtLine(@NotNull XLineBreakpointType<P> type, @NotNull VirtualFile file, int line);
|
||||
|
||||
|
||||
boolean isDefaultBreakpoint(@NotNull XBreakpoint<?> breakpoint);
|
||||
|
||||
<B extends XBreakpoint<P>, P extends XBreakpointProperties>
|
||||
void addBreakpointListener(@NotNull XBreakpointType<B,P> type, @NotNull XBreakpointListener<B> listener);
|
||||
|
||||
|
||||
@@ -39,8 +39,9 @@ import java.util.Comparator;
|
||||
* <extensions defaultExtensionNs="com.intellij"><br>
|
||||
* <xdebugger.breakpointType implementation="qualified-class-name"/><br>
|
||||
* </extensions>
|
||||
* <p><p>
|
||||
*
|
||||
* Use this class only for breakpoints like an exception breakpoints in Java. If a breakpoint will be put on some line in a file use
|
||||
* Use this class only for breakpoints like exception breakpoints in Java. If a breakpoint will be put on some line in a file use
|
||||
* {@link XLineBreakpointType} instead
|
||||
*
|
||||
* @author nik
|
||||
@@ -145,6 +146,17 @@ public abstract class XBreakpointType<B extends XBreakpoint<P>, P extends XBreak
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns properties of the default breakpoint. The default breakpoints cannot be deleted and is always shown on top of the breakpoints
|
||||
* list in the dialog. It is disabled by default.
|
||||
*
|
||||
* @return a default breakpoint properties or {@code null} if default breakpoint isn't supported
|
||||
*/
|
||||
@Nullable
|
||||
public P createDefaultBreakpointProperties() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @NonNls
|
||||
public String getBreakpointsDialogHelpTopic() {
|
||||
return null;
|
||||
|
||||
+9
-1
@@ -39,7 +39,7 @@ import java.util.Collections;
|
||||
* <extensions defaultExtensionNs="com.intellij"><br>
|
||||
* <xdebugger.breakpointType implementation="qualified-class-name"/><br>
|
||||
* </extensions>
|
||||
*
|
||||
* <p><p>
|
||||
* In order to support actual setting breakpoints in a debugging process create a {@link XBreakpointHandler} implementation and return it
|
||||
* from {@link com.intellij.xdebugger.XDebugProcess#getBreakpointHandlers()} method
|
||||
*
|
||||
@@ -85,6 +85,14 @@ public abstract class XLineBreakpointType<P extends XBreakpointProperties> exten
|
||||
return XDebuggerUtil.getInstance().getDefaultLineBreakpointComparator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default line breakpoints cannot be supported
|
||||
*/
|
||||
@Override
|
||||
public final P createDefaultBreakpointProperties() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<? extends AnAction> getAdditionalPopupMenuActions(@NotNull XLineBreakpoint<P> breakpoint, @Nullable XDebugSession currentSession) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
+112
-24
@@ -18,19 +18,24 @@ package com.intellij.xdebugger.impl.breakpoints;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.MultiValuesMap;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.ex.http.HttpFileSystem;
|
||||
import com.intellij.openapi.vfs.ex.http.HttpVirtualFileListener;
|
||||
import com.intellij.util.EventDispatcher;
|
||||
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
|
||||
import com.intellij.util.xmlb.XmlSerializer;
|
||||
import com.intellij.util.xmlb.annotations.AbstractCollection;
|
||||
import com.intellij.util.xmlb.annotations.MapAnnotation;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
import com.intellij.xdebugger.breakpoints.*;
|
||||
import com.intellij.xdebugger.impl.XDebuggerManagerImpl;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -41,7 +46,10 @@ import java.util.*;
|
||||
* @author nik
|
||||
*/
|
||||
public class XBreakpointManagerImpl implements XBreakpointManager, PersistentStateComponent<XBreakpointManagerImpl.BreakpointManagerState> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl");
|
||||
public static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTER = new SkipDefaultValuesSerializationFilters();
|
||||
private final MultiValuesMap<XBreakpointType, XBreakpointBase<?,?,?>> myBreakpoints = new MultiValuesMap<XBreakpointType, XBreakpointBase<?,?,?>>(true);
|
||||
private final Map<XBreakpointType, XBreakpointBase<?,?,?>> myDefaultBreakpoints = new LinkedHashMap<XBreakpointType, XBreakpointBase<?, ?, ?>>();
|
||||
private final Map<XBreakpointType, EventDispatcher<XBreakpointListener>> myDispatchers = new HashMap<XBreakpointType, EventDispatcher<XBreakpointListener>>();
|
||||
private final Map<XBreakpointType<?,?>, XBreakpointTypeDialogState> myBreakpointsDialogSettings = new HashMap<XBreakpointType<?,?>, XBreakpointTypeDialogState>();
|
||||
private final EventDispatcher<XBreakpointListener> myAllBreakpointsDispatcher;
|
||||
@@ -99,15 +107,29 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
@NotNull
|
||||
public <T extends XBreakpointProperties> XBreakpoint<T> addBreakpoint(final XBreakpointType<XBreakpoint<T>,T> type, @Nullable final T properties) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
XBreakpointBase.BreakpointState<?,T,?> state = new XBreakpointBase.BreakpointState<XBreakpoint<T>,T,XBreakpointType<XBreakpoint<T>,T>>(true, type.getId());
|
||||
return addBreakpoint(type, properties, false, true);
|
||||
}
|
||||
|
||||
private <T extends XBreakpointProperties> XBreakpointBase<?, T, ?> addBreakpoint(XBreakpointType<XBreakpoint<T>, T> type,
|
||||
T properties,
|
||||
final boolean defaultBreakpoint,
|
||||
final boolean initUI) {
|
||||
XBreakpointBase.BreakpointState<?,T,?> state = new XBreakpointBase.BreakpointState<XBreakpoint<T>,T,XBreakpointType<XBreakpoint<T>,T>>(!defaultBreakpoint, type.getId());
|
||||
XBreakpointBase<?,T, ?> breakpoint = new XBreakpointBase<XBreakpoint<T>,T, XBreakpointBase.BreakpointState<?,T,?>>(type, this, properties, state);
|
||||
addBreakpoint(breakpoint, true);
|
||||
addBreakpoint(breakpoint, defaultBreakpoint, initUI);
|
||||
return breakpoint;
|
||||
}
|
||||
|
||||
private <T extends XBreakpointProperties> void addBreakpoint(final XBreakpointBase<?,T,?> breakpoint, boolean initUI) {
|
||||
private <T extends XBreakpointProperties> void addBreakpoint(final XBreakpointBase<?, T, ?> breakpoint, final boolean defaultBreakpoint,
|
||||
boolean initUI) {
|
||||
XBreakpointType type = breakpoint.getType();
|
||||
myBreakpoints.put(type, breakpoint);
|
||||
if (defaultBreakpoint) {
|
||||
LOG.assertTrue(!myDefaultBreakpoints.containsKey(type), "Cannot have more than one default breakpoint (type " + type.getId() + ")");
|
||||
myDefaultBreakpoints.put(type, breakpoint);
|
||||
}
|
||||
else {
|
||||
myBreakpoints.put(type, breakpoint);
|
||||
}
|
||||
if (breakpoint instanceof XLineBreakpointImpl) {
|
||||
myLineBreakpointManager.registerBreakpoint((XLineBreakpointImpl)breakpoint, initUI);
|
||||
}
|
||||
@@ -138,6 +160,10 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
|
||||
public void removeBreakpoint(@NotNull final XBreakpoint<?> breakpoint) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
doRemoveBreakpoint(breakpoint);
|
||||
}
|
||||
|
||||
private void doRemoveBreakpoint(XBreakpoint<?> breakpoint) {
|
||||
XBreakpointType type = breakpoint.getType();
|
||||
XBreakpointBase<?,?,?> breakpointBase = (XBreakpointBase<?,?,?>)breakpoint;
|
||||
myBreakpoints.remove(type, breakpointBase);
|
||||
@@ -158,26 +184,32 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
final int line, @Nullable final T properties) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
XLineBreakpointImpl<T> breakpoint = new XLineBreakpointImpl<T>(type, this, fileUrl, line, properties);
|
||||
addBreakpoint(breakpoint, true);
|
||||
addBreakpoint(breakpoint, false, true);
|
||||
return breakpoint;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public XBreakpointBase<?,?,?>[] getAllBreakpoints() {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
Collection<XBreakpointBase<?,?,?>> breakpoints = myBreakpoints.values();
|
||||
List<XBreakpointBase<?, ?, ?>> breakpoints = new ArrayList<XBreakpointBase<?, ?, ?>>();
|
||||
breakpoints.addAll(myDefaultBreakpoints.values());
|
||||
breakpoints.addAll(myBreakpoints.values());
|
||||
return breakpoints.toArray(new XBreakpointBase[breakpoints.size()]);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@NotNull
|
||||
public <B extends XBreakpoint<?>> Collection<? extends B> getBreakpoints(@NotNull final XBreakpointType<B,?> type) {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
Collection<? extends XBreakpointBase<?,?,?>> breakpoints = myBreakpoints.get(type);
|
||||
if (breakpoints == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//noinspection unchecked
|
||||
return Collections.unmodifiableCollection((Collection<? extends B>)breakpoints);
|
||||
Collection<? extends B> regular = breakpoints != null ? Collections.unmodifiableCollection((Collection<? extends B>)breakpoints) : Collections.<B>emptyList();
|
||||
|
||||
final XBreakpointBase<?, ?, ?> defaultBreakpoint = myDefaultBreakpoints.get(type);
|
||||
if (defaultBreakpoint == null) return regular;
|
||||
List<B> result = new ArrayList<B>();
|
||||
result.add((B)defaultBreakpoint);
|
||||
result.addAll(regular);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -196,6 +228,12 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaultBreakpoint(@NotNull XBreakpoint<?> breakpoint) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
return myDefaultBreakpoints.values().contains(breakpoint);
|
||||
}
|
||||
|
||||
private <T extends XBreakpointProperties> EventDispatcher<XBreakpointListener> getOrCreateDispatcher(final XBreakpointType<?,T> type) {
|
||||
EventDispatcher<XBreakpointListener> dispatcher = myDispatchers.get(type);
|
||||
if (dispatcher == null) {
|
||||
@@ -242,6 +280,12 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
public BreakpointManagerState getState() {
|
||||
myDependentBreakpointManager.saveState();
|
||||
BreakpointManagerState state = new BreakpointManagerState();
|
||||
for (XBreakpointBase<?, ?, ?> breakpoint : myDefaultBreakpoints.values()) {
|
||||
final XBreakpointBase.BreakpointState breakpointState = breakpoint.getState();
|
||||
if (differsFromDefault(breakpoint.getType(), breakpointState)) {
|
||||
state.getDefaultBreakpoints().add(breakpointState);
|
||||
}
|
||||
}
|
||||
for (XBreakpointBase<?,?,?> breakpoint : myBreakpoints.values()) {
|
||||
state.getBreakpoints().add(breakpoint.getState());
|
||||
}
|
||||
@@ -251,6 +295,19 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
return state;
|
||||
}
|
||||
|
||||
private static <P extends XBreakpointProperties> boolean differsFromDefault(XBreakpointType<?, P> type,
|
||||
XBreakpointBase.BreakpointState state) {
|
||||
final P defaultProperties = type.createDefaultBreakpointProperties();
|
||||
if (defaultProperties == null) {
|
||||
return false;
|
||||
}
|
||||
XBreakpointBase.BreakpointState defaultState = new XBreakpointBase.BreakpointState(false, type.getId());
|
||||
defaultState.setPropertiesElement(XmlSerializer.serialize(defaultProperties));
|
||||
Element defaultElement = XmlSerializer.serialize(defaultState, SERIALIZATION_FILTER);
|
||||
Element currentElement = XmlSerializer.serialize(state, SERIALIZATION_FILTER);
|
||||
return !JDOMUtil.areElementsEqual(defaultElement, currentElement);
|
||||
}
|
||||
|
||||
public void loadState(final BreakpointManagerState state) {
|
||||
myBreakpointsDialogSettings.clear();
|
||||
for (Map.Entry<String, XBreakpointTypeDialogState> entry : state.getBreakpointTypeDialogProperties().entrySet()) {
|
||||
@@ -260,17 +317,41 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
}
|
||||
}
|
||||
|
||||
removeAllBreakpoints();
|
||||
for (XBreakpointBase.BreakpointState breakpointState : state.getBreakpoints()) {
|
||||
XBreakpointBase<?,?,?> breakpoint = createBreakpoint(breakpointState);
|
||||
if (breakpoint != null) {
|
||||
addBreakpoint(breakpoint, false);
|
||||
myDefaultBreakpoints.clear();
|
||||
for (XBreakpointBase.BreakpointState breakpointState : state.getDefaultBreakpoints()) {
|
||||
loadBreakpoint(breakpointState, true);
|
||||
}
|
||||
for (XBreakpointType<?, ?> type : XBreakpointUtil.getBreakpointTypes()) {
|
||||
if (!myDefaultBreakpoints.containsKey(type)) {
|
||||
addDefaultBreakpoint(type);
|
||||
}
|
||||
}
|
||||
|
||||
for (XBreakpointBase<?,?,?> breakpoint : myBreakpoints.values()) {
|
||||
doRemoveBreakpoint(breakpoint);
|
||||
}
|
||||
for (XBreakpointBase.BreakpointState breakpointState : state.getBreakpoints()) {
|
||||
loadBreakpoint(breakpointState, false);
|
||||
}
|
||||
myDependentBreakpointManager.loadState();
|
||||
myLineBreakpointManager.updateBreakpointsUI();
|
||||
}
|
||||
|
||||
private <P extends XBreakpointProperties> void addDefaultBreakpoint(XBreakpointType<?, P> type) {
|
||||
final P properties = type.createDefaultBreakpointProperties();
|
||||
if (properties != null) {
|
||||
//noinspection unchecked
|
||||
addBreakpoint((XBreakpointType<XBreakpoint<P>, P>)type, properties, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadBreakpoint(XBreakpointBase.BreakpointState breakpointState, final boolean defaultBreakpoint) {
|
||||
XBreakpointBase<?,?,?> breakpoint = createBreakpoint(breakpointState);
|
||||
if (breakpoint != null) {
|
||||
addBreakpoint(breakpoint, defaultBreakpoint, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public XBreakpointTypeDialogState getDialogState(@NotNull XBreakpointType<?, ?> type) {
|
||||
return myBreakpointsDialogSettings.get(type);
|
||||
@@ -280,27 +361,30 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
myBreakpointsDialogSettings.put(type, dialogState);
|
||||
}
|
||||
|
||||
private void removeAllBreakpoints() {
|
||||
for (XBreakpointBase<?,?,?> breakpoint : myBreakpoints.values()) {
|
||||
removeBreakpoint(breakpoint);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private XBreakpointBase<?,?,?> createBreakpoint(final XBreakpointBase.BreakpointState breakpointState) {
|
||||
XBreakpointType<?,?> type = XBreakpointUtil.findType(breakpointState.getTypeId());
|
||||
if (type == null) return null;
|
||||
if (type == null) return null;
|
||||
//noinspection unchecked
|
||||
return breakpointState.createBreakpoint(type, this);
|
||||
}
|
||||
|
||||
|
||||
@Tag("breakpoint-manager")
|
||||
public static class BreakpointManagerState {
|
||||
private List<XBreakpointBase.BreakpointState> myDefaultBreakpoints = new ArrayList<XBreakpointBase.BreakpointState>();
|
||||
private List<XBreakpointBase.BreakpointState> myBreakpoints = new ArrayList<XBreakpointBase.BreakpointState>();
|
||||
private Map<String, XBreakpointTypeDialogState> myBreakpointTypeDialogProperties = new HashMap<String, XBreakpointTypeDialogState>();
|
||||
|
||||
@Tag("default-breakpoints")
|
||||
@AbstractCollection(surroundWithTag = false)
|
||||
public List<XBreakpointBase.BreakpointState> getDefaultBreakpoints() {
|
||||
return myDefaultBreakpoints;
|
||||
}
|
||||
|
||||
@Tag("breakpoints")
|
||||
@AbstractCollection(surroundWithTag = false, elementTypes = {XBreakpointBase.BreakpointState.class, XLineBreakpointImpl.LineBreakpointState.class})
|
||||
@AbstractCollection(surroundWithTag = false,
|
||||
elementTypes = {XBreakpointBase.BreakpointState.class, XLineBreakpointImpl.LineBreakpointState.class})
|
||||
public List<XBreakpointBase.BreakpointState> getBreakpoints() {
|
||||
return myBreakpoints;
|
||||
}
|
||||
@@ -316,6 +400,10 @@ public class XBreakpointManagerImpl implements XBreakpointManager, PersistentSta
|
||||
myBreakpoints = breakpoints;
|
||||
}
|
||||
|
||||
public void setDefaultBreakpoints(List<XBreakpointBase.BreakpointState> defaultBreakpoints) {
|
||||
myDefaultBreakpoints = defaultBreakpoints;
|
||||
}
|
||||
|
||||
public void setBreakpointTypeDialogProperties(final Map<String, XBreakpointTypeDialogState> breakpointTypeDialogProperties) {
|
||||
myBreakpointTypeDialogProperties = breakpointTypeDialogProperties;
|
||||
}
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ public class XBreakpointsPanel<B extends XBreakpoint<?>> extends AbstractBreakpo
|
||||
myAllGroupingRules = new ArrayList<XBreakpointGroupingRule<B,?>>(myType.getGroupingRules());
|
||||
mySelectedGroupingRules = getInitialGroupingRules();
|
||||
|
||||
myTree = XBreakpointsTree.createTree(myType, mySelectedGroupingRules, myParentDialog);
|
||||
myTree = XBreakpointsTree.createTree(myType, mySelectedGroupingRules, myParentDialog, getBreakpointManager());
|
||||
myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
|
||||
public void valueChanged(final TreeSelectionEvent e) {
|
||||
onSelectionChanged();
|
||||
|
||||
+16
-5
@@ -25,6 +25,7 @@ import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpoint;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointType;
|
||||
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
|
||||
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
|
||||
@@ -53,11 +54,13 @@ public class XBreakpointsTree<B extends XBreakpoint<?>> extends CheckboxTree {
|
||||
private final MultiValuesMap<XBreakpointGroupingRule<B, ?>, XBreakpointGroup> myGroups = new MultiValuesMap<XBreakpointGroupingRule<B,?>, XBreakpointGroup>();
|
||||
|
||||
private XBreakpointsTree(final XBreakpointType<B, ?> type, final CheckedTreeNode root,
|
||||
Collection<XBreakpointGroupingRule<B, ?>> groupingRules, DialogWrapper parentDialog) {
|
||||
Collection<XBreakpointGroupingRule<B, ?>> groupingRules,
|
||||
DialogWrapper parentDialog,
|
||||
XBreakpointManager breakpointManager) {
|
||||
super(new BreakpointsTreeCellRenderer(), root);
|
||||
myRoot = root;
|
||||
myParentDialog = parentDialog;
|
||||
myComparator = new TreeNodeComparator<B>(type);
|
||||
myComparator = new TreeNodeComparator<B>(type, breakpointManager);
|
||||
setGroupingRulesInternal(groupingRules);
|
||||
}
|
||||
|
||||
@@ -68,8 +71,8 @@ public class XBreakpointsTree<B extends XBreakpoint<?>> extends CheckboxTree {
|
||||
|
||||
public static <B extends XBreakpoint<?>> XBreakpointsTree<B> createTree(final XBreakpointType<B, ?> type,
|
||||
final Collection<XBreakpointGroupingRule<B, ?>> groupingRules,
|
||||
DialogWrapper parentDialog) {
|
||||
return new XBreakpointsTree<B>(type, new CheckedTreeNode("root"), groupingRules, parentDialog);
|
||||
DialogWrapper parentDialog, XBreakpointManager breakpointManager) {
|
||||
return new XBreakpointsTree<B>(type, new CheckedTreeNode("root"), groupingRules, parentDialog, breakpointManager);
|
||||
}
|
||||
|
||||
public void buildTree(@NotNull Collection<? extends B> breakpoints) {
|
||||
@@ -254,15 +257,23 @@ public class XBreakpointsTree<B extends XBreakpoint<?>> extends CheckboxTree {
|
||||
|
||||
private static class TreeNodeComparator<B extends XBreakpoint<?>> implements Comparator<TreeNode> {
|
||||
private final Comparator<B> myBreakpointComparator;
|
||||
private final XBreakpointManager myBreakpointManager;
|
||||
|
||||
public TreeNodeComparator(final XBreakpointType<B, ?> type) {
|
||||
public TreeNodeComparator(final XBreakpointType<B, ?> type, XBreakpointManager breakpointManager) {
|
||||
myBreakpointManager = breakpointManager;
|
||||
myBreakpointComparator = type.getBreakpointComparator();
|
||||
}
|
||||
|
||||
public int compare(final TreeNode o1, final TreeNode o2) {
|
||||
if (o1 instanceof BreakpointNode && o2 instanceof BreakpointNode) {
|
||||
//noinspection unchecked
|
||||
B b1 = (B)((BreakpointNode)o1).getBreakpoint();
|
||||
//noinspection unchecked
|
||||
B b2 = (B)((BreakpointNode)o2).getBreakpoint();
|
||||
boolean default1 = myBreakpointManager.isDefaultBreakpoint(b1);
|
||||
boolean default2 = myBreakpointManager.isDefaultBreakpoint(b2);
|
||||
if (default1 && !default2) return -1;
|
||||
if (!default1 && default2) return 1;
|
||||
return myBreakpointComparator.compare(b1, b2);
|
||||
}
|
||||
if (o1 instanceof BreakpointsGroupNode && o2 instanceof BreakpointsGroupNode) {
|
||||
|
||||
+9
-2
@@ -38,7 +38,12 @@ public class RemoveBreakpointAction<B extends XBreakpoint<?>> extends XBreakpoin
|
||||
}
|
||||
|
||||
public boolean isEnabled(@NotNull final Collection<? extends B> breakpoints) {
|
||||
return !breakpoints.isEmpty();
|
||||
for (B breakpoint : breakpoints) {
|
||||
if (!myBreakpointsPanel.getBreakpointManager().isDefaultBreakpoint(breakpoint)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void perform(@NotNull final Collection<? extends B> breakpoints) {
|
||||
@@ -46,7 +51,9 @@ public class RemoveBreakpointAction<B extends XBreakpoint<?>> extends XBreakpoin
|
||||
new WriteAction() {
|
||||
protected void run(final Result result) {
|
||||
for (B breakpoint : breakpoints) {
|
||||
breakpointManager.removeBreakpoint(breakpoint);
|
||||
if (!breakpointManager.isDefaultBreakpoint(breakpoint)) {
|
||||
breakpointManager.removeBreakpoint(breakpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
|
||||
+47
-10
@@ -35,12 +35,12 @@ public class XBreakpointManagerTest extends XBreakpointsTestCase {
|
||||
|
||||
assertSameElements(myBreakpointManager.getAllBreakpoints(), breakpoint, lineBreakpoint);
|
||||
assertSame(lineBreakpoint, assertOneElement(myBreakpointManager.getBreakpoints(MY_LINE_BREAKPOINT_TYPE)));
|
||||
assertSame(breakpoint, assertOneElement(myBreakpointManager.getBreakpoints(MY_SIMPLE_BREAKPOINT_TYPE)));
|
||||
assertSame(breakpoint, getSingleBreakpoint());
|
||||
|
||||
myBreakpointManager.removeBreakpoint(lineBreakpoint);
|
||||
assertSame(breakpoint, assertOneElement(myBreakpointManager.getAllBreakpoints()));
|
||||
assertTrue(myBreakpointManager.getBreakpoints(MY_LINE_BREAKPOINT_TYPE).isEmpty());
|
||||
assertSame(breakpoint, assertOneElement(myBreakpointManager.getBreakpoints(MY_SIMPLE_BREAKPOINT_TYPE)));
|
||||
assertSame(breakpoint, getSingleBreakpoint());
|
||||
|
||||
myBreakpointManager.removeBreakpoint(breakpoint);
|
||||
assertEquals(0, myBreakpointManager.getAllBreakpoints().length);
|
||||
@@ -56,13 +56,14 @@ public class XBreakpointManagerTest extends XBreakpointsTestCase {
|
||||
breakpoint.setLogMessage(true);
|
||||
myBreakpointManager.addBreakpoint(MY_SIMPLE_BREAKPOINT_TYPE, new MyBreakpointProperties("123"));
|
||||
|
||||
Element element = save();
|
||||
//System.out.println(JDOMUtil.writeElement(element, SystemProperties.getLineSeparator()));
|
||||
load(element);
|
||||
reload();
|
||||
XBreakpoint<?>[] breakpoints = myBreakpointManager.getAllBreakpoints();
|
||||
assertEquals(2, breakpoints.length);
|
||||
assertEquals(3, breakpoints.length);
|
||||
|
||||
XLineBreakpoint lineBreakpoint = assertInstanceOf(breakpoints[0], XLineBreakpoint.class);
|
||||
assertTrue(myBreakpointManager.isDefaultBreakpoint(breakpoints[0]));
|
||||
assertEquals("default", assertInstanceOf(breakpoints[0].getProperties(), MyBreakpointProperties.class).myOption);
|
||||
|
||||
XLineBreakpoint lineBreakpoint = assertInstanceOf(breakpoints[1], XLineBreakpoint.class);
|
||||
assertEquals(239, lineBreakpoint.getLine());
|
||||
assertEquals("myurl", lineBreakpoint.getFileUrl());
|
||||
assertEquals("abc", assertInstanceOf(lineBreakpoint.getProperties(), MyBreakpointProperties.class).myOption);
|
||||
@@ -71,9 +72,36 @@ public class XBreakpointManagerTest extends XBreakpointsTestCase {
|
||||
assertTrue(lineBreakpoint.isLogMessage());
|
||||
assertEquals(SuspendPolicy.NONE, lineBreakpoint.getSuspendPolicy());
|
||||
|
||||
assertEquals("123", assertInstanceOf(breakpoints[1].getProperties(), MyBreakpointProperties.class).myOption);
|
||||
assertEquals(SuspendPolicy.ALL, breakpoints[1].getSuspendPolicy());
|
||||
assertFalse(breakpoints[1].isLogMessage());
|
||||
assertEquals("123", assertInstanceOf(breakpoints[2].getProperties(), MyBreakpointProperties.class).myOption);
|
||||
assertEquals(SuspendPolicy.ALL, breakpoints[2].getSuspendPolicy());
|
||||
assertFalse(breakpoints[2].isLogMessage());
|
||||
}
|
||||
|
||||
public void testDoNotSaveUnmodifiedDefaultBreakpoint() throws Exception {
|
||||
reload();
|
||||
|
||||
assertEquals("default", getSingleBreakpoint().getProperties().myOption);
|
||||
Element element = save();
|
||||
assertEquals(0, element.getContent().size());
|
||||
}
|
||||
|
||||
public void testSaveEnabledDefaultBreakpoint() throws Exception {
|
||||
reload();
|
||||
final XBreakpoint<MyBreakpointProperties> breakpoint = getSingleBreakpoint();
|
||||
breakpoint.setEnabled(true);
|
||||
|
||||
assertFalse(save().getContent().isEmpty());
|
||||
reload();
|
||||
assertTrue(getSingleBreakpoint().isEnabled());
|
||||
}
|
||||
|
||||
public void testSaveDefaultBreakpointWithModifiedProperties() throws Exception {
|
||||
reload();
|
||||
getSingleBreakpoint().getProperties().myOption = "changed";
|
||||
|
||||
assertFalse(save().getContent().isEmpty());
|
||||
reload();
|
||||
assertEquals("changed", getSingleBreakpoint().getProperties().myOption);
|
||||
}
|
||||
|
||||
public void testListener() throws Exception {
|
||||
@@ -106,4 +134,13 @@ public class XBreakpointManagerTest extends XBreakpointsTestCase {
|
||||
myBreakpointManager.addLineBreakpoint(MY_LINE_BREAKPOINT_TYPE, "url", 239, new MyBreakpointProperties("a"));
|
||||
assertEquals("", out.toString());
|
||||
}
|
||||
|
||||
private XBreakpoint<MyBreakpointProperties> getSingleBreakpoint() {
|
||||
return assertOneElement(myBreakpointManager.getBreakpoints(MY_SIMPLE_BREAKPOINT_TYPE));
|
||||
}
|
||||
|
||||
private void reload() {
|
||||
Element element = save();
|
||||
load(element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,11 @@ public abstract class XDebuggerTestCase extends PlatformLiteFixture {
|
||||
public MyBreakpointProperties createProperties() {
|
||||
return new MyBreakpointProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyBreakpointProperties createDefaultBreakpointProperties() {
|
||||
return new MyBreakpointProperties("default");
|
||||
}
|
||||
}
|
||||
|
||||
protected static class MyBreakpointProperties extends XBreakpointProperties<MyBreakpointProperties> {
|
||||
|
||||
Reference in New Issue
Block a user