2 * Copyright 2000-2016 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Class BreakpointManager
21 package com.intellij.debugger.ui.breakpoints;
23 import com.intellij.debugger.DebuggerBundle;
24 import com.intellij.debugger.DebuggerInvocationUtil;
25 import com.intellij.debugger.engine.BreakpointStepMethodFilter;
26 import com.intellij.debugger.engine.DebugProcessImpl;
27 import com.intellij.debugger.engine.requests.RequestManagerImpl;
28 import com.intellij.debugger.impl.DebuggerContextImpl;
29 import com.intellij.debugger.impl.DebuggerContextListener;
30 import com.intellij.debugger.impl.DebuggerManagerImpl;
31 import com.intellij.debugger.impl.DebuggerSession;
32 import com.intellij.debugger.ui.JavaDebuggerSupport;
33 import com.intellij.openapi.application.ApplicationManager;
34 import com.intellij.openapi.diagnostic.Logger;
35 import com.intellij.openapi.editor.Document;
36 import com.intellij.openapi.editor.Editor;
37 import com.intellij.openapi.editor.markup.GutterIconRenderer;
38 import com.intellij.openapi.editor.markup.RangeHighlighter;
39 import com.intellij.openapi.fileEditor.FileDocumentManager;
40 import com.intellij.openapi.project.Project;
41 import com.intellij.openapi.startup.StartupManager;
42 import com.intellij.openapi.ui.MessageType;
43 import com.intellij.openapi.util.Comparing;
44 import com.intellij.openapi.util.Computable;
45 import com.intellij.openapi.util.InvalidDataException;
46 import com.intellij.openapi.util.Key;
47 import com.intellij.openapi.vfs.VirtualFile;
48 import com.intellij.openapi.vfs.VirtualFileManager;
49 import com.intellij.psi.PsiField;
50 import com.intellij.util.containers.ContainerUtil;
51 import com.intellij.xdebugger.XDebuggerManager;
52 import com.intellij.xdebugger.XDebuggerUtil;
53 import com.intellij.xdebugger.XSourcePosition;
54 import com.intellij.xdebugger.breakpoints.*;
55 import com.intellij.xdebugger.impl.DebuggerSupport;
56 import com.intellij.xdebugger.impl.XDebugSessionImpl;
57 import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
58 import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
59 import com.intellij.xdebugger.impl.breakpoints.XDependentBreakpointManager;
60 import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl;
61 import com.sun.jdi.InternalException;
62 import com.sun.jdi.ThreadReference;
63 import com.sun.jdi.request.*;
64 import gnu.trove.THashMap;
65 import org.jdom.Element;
66 import org.jetbrains.annotations.NonNls;
67 import org.jetbrains.annotations.NotNull;
68 import org.jetbrains.annotations.Nullable;
69 import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties;
72 import java.util.LinkedHashMap;
73 import java.util.List;
76 public class BreakpointManager {
77 private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.BreakpointManager");
79 @NonNls private static final String MASTER_BREAKPOINT_TAG_NAME = "master_breakpoint";
80 @NonNls private static final String SLAVE_BREAKPOINT_TAG_NAME = "slave_breakpoint";
81 @NonNls private static final String DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME = "default_suspend_policy";
82 @NonNls private static final String DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME = "default_condition_enabled";
84 @NonNls private static final String RULES_GROUP_NAME = "breakpoint_rules";
85 private static final String CONVERTED_PARAM = "converted";
87 private final Project myProject;
88 private final Map<String, String> myUIProperties = new LinkedHashMap<>();
90 private final StartupManager myStartupManager;
92 public BreakpointManager(@NotNull Project project, @NotNull StartupManager startupManager, @NotNull DebuggerManagerImpl debuggerManager) {
94 myStartupManager = startupManager;
95 debuggerManager.getContextManager().addListener(new DebuggerContextListener() {
96 private DebuggerSession myPreviousSession;
99 public void changeEvent(@NotNull DebuggerContextImpl newContext, DebuggerSession.Event event) {
100 if (event == DebuggerSession.Event.ATTACHED) {
101 for (XBreakpoint breakpoint : getXBreakpointManager().getAllBreakpoints()) {
102 if (checkAndNotifyPossiblySlowBreakpoint(breakpoint)) break;
105 if (newContext.getDebuggerSession() != myPreviousSession || event == DebuggerSession.Event.DETACHED) {
106 updateBreakpointsUI();
107 myPreviousSession = newContext.getDebuggerSession();
113 private static boolean checkAndNotifyPossiblySlowBreakpoint(XBreakpoint breakpoint) {
114 if (breakpoint.isEnabled() &&
115 (breakpoint.getType() instanceof JavaMethodBreakpointType || breakpoint.getType() instanceof JavaWildcardMethodBreakpointType)) {
116 Breakpoint bpt = getJavaBreakpoint(breakpoint);
117 if (bpt instanceof MethodBreakpoint && ((MethodBreakpoint)bpt).isEmulated()) {
120 XDebugSessionImpl.NOTIFICATION_GROUP
121 .createNotification(DebuggerBundle.message("method.breakpoints.slowness.warning"), MessageType.WARNING)
122 .notify(((XBreakpointBase)breakpoint).getProject());
129 XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager();
130 manager.addBreakpointListener(new XBreakpointAdapter<XBreakpoint<?>>() {
132 public void breakpointAdded(@NotNull XBreakpoint<?> xBreakpoint) {
133 Breakpoint breakpoint = getJavaBreakpoint(xBreakpoint);
134 if (breakpoint != null) {
135 addBreakpoint(breakpoint);
140 public void breakpointChanged(@NotNull XBreakpoint xBreakpoint) {
141 Breakpoint breakpoint = getJavaBreakpoint(xBreakpoint);
142 if (breakpoint != null) {
143 fireBreakpointChanged(breakpoint);
149 private XBreakpointManager getXBreakpointManager() {
150 return XDebuggerManager.getInstance(myProject).getBreakpointManager();
153 public void editBreakpoint(final Breakpoint breakpoint, final Editor editor) {
154 DebuggerInvocationUtil.swingInvokeLater(myProject, () -> {
155 XBreakpoint xBreakpoint = breakpoint.myXBreakpoint;
156 if (xBreakpoint instanceof XLineBreakpointImpl) {
157 RangeHighlighter highlighter = ((XLineBreakpointImpl)xBreakpoint).getHighlighter();
158 if (highlighter != null) {
159 GutterIconRenderer renderer = highlighter.getGutterIconRenderer();
160 if (renderer != null) {
161 DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class).getEditBreakpointAction().editBreakpoint(
162 myProject, editor, breakpoint.myXBreakpoint, renderer
170 public void setBreakpointDefaults(Key<? extends Breakpoint> category, BreakpointDefaults defaults) {
171 Class typeCls = null;
172 if (LineBreakpoint.CATEGORY.toString().equals(category.toString())) {
173 typeCls = JavaLineBreakpointType.class;
175 else if (MethodBreakpoint.CATEGORY.toString().equals(category.toString())) {
176 typeCls = JavaMethodBreakpointType.class;
178 else if (FieldBreakpoint.CATEGORY.toString().equals(category.toString())) {
179 typeCls = JavaFieldBreakpointType.class;
181 else if (ExceptionBreakpoint.CATEGORY.toString().equals(category.toString())) {
182 typeCls = JavaExceptionBreakpointType.class;
184 if (typeCls != null) {
185 XBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
186 ((XBreakpointManagerImpl)getXBreakpointManager()).getBreakpointDefaults(type).setSuspendPolicy(Breakpoint.transformSuspendPolicy(defaults.getSuspendPolicy()));
191 public RunToCursorBreakpoint addRunToCursorBreakpoint(@NotNull XSourcePosition position, final boolean ignoreBreakpoints) {
192 return RunToCursorBreakpoint.create(myProject, position, ignoreBreakpoints);
196 public StepIntoBreakpoint addStepIntoBreakpoint(@NotNull BreakpointStepMethodFilter filter) {
197 return StepIntoBreakpoint.create(myProject, filter);
201 public LineBreakpoint addLineBreakpoint(Document document, int lineIndex) {
202 ApplicationManager.getApplication().assertIsDispatchThread();
203 if (!LineBreakpoint.canAddLineBreakpoint(myProject, document, lineIndex)) {
206 XLineBreakpoint xLineBreakpoint = addXLineBreakpoint(JavaLineBreakpointType.class, document, lineIndex);
207 Breakpoint breakpoint = getJavaBreakpoint(xLineBreakpoint);
208 if (breakpoint instanceof LineBreakpoint) {
209 addBreakpoint(breakpoint);
210 return ((LineBreakpoint)breakpoint);
216 public FieldBreakpoint addFieldBreakpoint(@NotNull Document document, int offset) {
217 PsiField field = FieldBreakpoint.findField(myProject, document, offset);
222 int line = document.getLineNumber(offset);
224 if (document.getLineNumber(field.getNameIdentifier().getTextOffset()) < line) {
228 return addFieldBreakpoint(document, line, field.getName());
232 public FieldBreakpoint addFieldBreakpoint(Document document, int lineIndex, String fieldName) {
233 ApplicationManager.getApplication().assertIsDispatchThread();
234 XLineBreakpoint xBreakpoint = addXLineBreakpoint(JavaFieldBreakpointType.class, document, lineIndex);
235 Breakpoint javaBreakpoint = getJavaBreakpoint(xBreakpoint);
236 if (javaBreakpoint instanceof FieldBreakpoint) {
237 FieldBreakpoint fieldBreakpoint = (FieldBreakpoint)javaBreakpoint;
238 fieldBreakpoint.setFieldName(fieldName);
239 addBreakpoint(javaBreakpoint);
240 return fieldBreakpoint;
246 public ExceptionBreakpoint addExceptionBreakpoint(@NotNull final String exceptionClassName, final String packageName) {
247 ApplicationManager.getApplication().assertIsDispatchThread();
248 final JavaExceptionBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class);
249 return ApplicationManager.getApplication().runWriteAction((Computable<ExceptionBreakpoint>)() -> {
250 XBreakpoint<JavaExceptionBreakpointProperties> xBreakpoint = XDebuggerManager.getInstance(myProject).getBreakpointManager()
251 .addBreakpoint(type, new JavaExceptionBreakpointProperties(exceptionClassName, packageName));
252 Breakpoint javaBreakpoint = getJavaBreakpoint(xBreakpoint);
253 if (javaBreakpoint instanceof ExceptionBreakpoint) {
254 ExceptionBreakpoint exceptionBreakpoint = (ExceptionBreakpoint)javaBreakpoint;
255 exceptionBreakpoint.setQualifiedName(exceptionClassName);
256 exceptionBreakpoint.setPackageName(packageName);
257 addBreakpoint(exceptionBreakpoint);
258 LOG.debug("ExceptionBreakpoint Added");
259 return exceptionBreakpoint;
266 public MethodBreakpoint addMethodBreakpoint(Document document, int lineIndex) {
267 ApplicationManager.getApplication().assertIsDispatchThread();
269 XLineBreakpoint xBreakpoint = addXLineBreakpoint(JavaMethodBreakpointType.class, document, lineIndex);
270 Breakpoint javaBreakpoint = getJavaBreakpoint(xBreakpoint);
271 if (javaBreakpoint instanceof MethodBreakpoint) {
272 addBreakpoint(javaBreakpoint);
273 return (MethodBreakpoint)javaBreakpoint;
278 private <B extends XBreakpoint<?>> XLineBreakpoint addXLineBreakpoint(Class<? extends XBreakpointType<B,?>> typeCls, Document document, final int lineIndex) {
279 final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
280 final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
281 return ApplicationManager.getApplication().runWriteAction((Computable<XLineBreakpoint>)() -> XDebuggerManager.getInstance(myProject).getBreakpointManager()
282 .addLineBreakpoint((XLineBreakpointType)type, file.getUrl(), lineIndex,
283 ((XLineBreakpointType)type).createBreakpointProperties(file, lineIndex)));
287 * @param category breakpoint category, null if the category does not matter
290 public <T extends BreakpointWithHighlighter> T findBreakpoint(final Document document, final int offset, @Nullable final Key<T> category) {
291 for (final Breakpoint breakpoint : getBreakpoints()) {
292 if (breakpoint instanceof BreakpointWithHighlighter && ((BreakpointWithHighlighter)breakpoint).isAt(document, offset)) {
293 if (category == null || category.equals(breakpoint.getCategory())) {
294 //noinspection CastConflictsWithInstanceof,unchecked
295 return (T)breakpoint;
302 private final Map<String, Element> myOriginalBreakpointsNodes = new LinkedHashMap<>();
304 public void readExternal(@NotNull final Element parentNode) {
305 myOriginalBreakpointsNodes.clear();
306 // save old breakpoints
307 for (Element element : parentNode.getChildren()) {
308 myOriginalBreakpointsNodes.put(element.getName(), element.clone());
310 myStartupManager.runWhenProjectIsInitialized(() -> doRead(parentNode));
313 private void doRead(@NotNull final Element parentNode) {
314 ApplicationManager.getApplication().runReadAction(() -> {
315 final Map<String, Breakpoint> nameToBreakpointMap = new THashMap<>();
317 final List groups = parentNode.getChildren();
318 for (final Object group1 : groups) {
319 final Element group = (Element)group1;
320 if (group.getName().equals(RULES_GROUP_NAME)) {
323 // skip already converted
324 if (group.getAttribute(CONVERTED_PARAM) != null) {
327 final String categoryName = group.getName();
328 final Key<Breakpoint> breakpointCategory = BreakpointCategory.lookup(categoryName);
329 final String defaultPolicy = group.getAttributeValue(DEFAULT_SUSPEND_POLICY_ATTRIBUTE_NAME);
330 final boolean conditionEnabled = Boolean.parseBoolean(group.getAttributeValue(DEFAULT_CONDITION_STATE_ATTRIBUTE_NAME, "true"));
331 setBreakpointDefaults(breakpointCategory, new BreakpointDefaults(defaultPolicy, conditionEnabled));
332 Element anyExceptionBreakpointGroup;
333 if (!AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT.equals(breakpointCategory)) {
334 // for compatibility with previous format
335 anyExceptionBreakpointGroup = group.getChild(AnyExceptionBreakpoint.ANY_EXCEPTION_BREAKPOINT.toString());
336 //final BreakpointFactory factory = BreakpointFactory.getInstance(breakpointCategory);
337 //if (factory != null) {
338 for (Element breakpointNode : group.getChildren("breakpoint")) {
339 //Breakpoint breakpoint = factory.createBreakpoint(myProject, breakpointNode);
340 Breakpoint breakpoint = createBreakpoint(categoryName, breakpointNode);
341 breakpoint.readExternal(breakpointNode);
342 nameToBreakpointMap.put(breakpoint.getDisplayName(), breakpoint);
347 anyExceptionBreakpointGroup = group;
350 if (anyExceptionBreakpointGroup != null) {
351 final Element breakpointElement = group.getChild("breakpoint");
352 if (breakpointElement != null) {
353 XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager();
354 JavaExceptionBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class);
355 XBreakpoint<JavaExceptionBreakpointProperties> xBreakpoint = manager.getDefaultBreakpoint(type);
356 Breakpoint breakpoint = getJavaBreakpoint(xBreakpoint);
357 if (breakpoint != null) {
358 breakpoint.readExternal(breakpointElement);
359 addBreakpoint(breakpoint);
365 catch (InvalidDataException ignored) {
368 final Element rulesGroup = parentNode.getChild(RULES_GROUP_NAME);
369 if (rulesGroup != null) {
370 final List<Element> rules = rulesGroup.getChildren("rule");
371 for (Element rule : rules) {
372 // skip already converted
373 if (rule.getAttribute(CONVERTED_PARAM) != null) {
376 final Element master = rule.getChild(MASTER_BREAKPOINT_TAG_NAME);
377 if (master == null) {
380 final Element slave = rule.getChild(SLAVE_BREAKPOINT_TAG_NAME);
384 final Breakpoint masterBreakpoint = nameToBreakpointMap.get(master.getAttributeValue("name"));
385 if (masterBreakpoint == null) {
388 final Breakpoint slaveBreakpoint = nameToBreakpointMap.get(slave.getAttributeValue("name"));
389 if (slaveBreakpoint == null) {
393 boolean leaveEnabled = "true".equalsIgnoreCase(rule.getAttributeValue("leaveEnabled"));
394 XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager();
395 dependentBreakpointManager.setMasterBreakpoint(slaveBreakpoint.myXBreakpoint, masterBreakpoint.myXBreakpoint, leaveEnabled);
396 //addBreakpointRule(new EnableBreakpointRule(BreakpointManager.this, masterBreakpoint, slaveBreakpoint, leaveEnabled));
400 DebuggerInvocationUtil.invokeLater(myProject, this::updateBreakpointsUI);
403 myUIProperties.clear();
404 final Element props = parentNode.getChild("ui_properties");
406 final List children = props.getChildren("property");
407 for (Object child : children) {
408 Element property = (Element)child;
409 final String name = property.getAttributeValue("name");
410 final String value = property.getAttributeValue("value");
411 if (name != null && value != null) {
412 myUIProperties.put(name, value);
418 private Breakpoint createBreakpoint(String category, Element breakpointNode) throws InvalidDataException {
419 XBreakpoint xBreakpoint = null;
420 if (category.equals(LineBreakpoint.CATEGORY.toString())) {
421 xBreakpoint = createXLineBreakpoint(JavaLineBreakpointType.class, breakpointNode);
423 else if (category.equals(MethodBreakpoint.CATEGORY.toString())) {
424 if (breakpointNode.getAttribute("url") != null) {
425 xBreakpoint = createXLineBreakpoint(JavaMethodBreakpointType.class, breakpointNode);
428 xBreakpoint = createXBreakpoint(JavaWildcardMethodBreakpointType.class);
431 else if (category.equals(FieldBreakpoint.CATEGORY.toString())) {
432 xBreakpoint = createXLineBreakpoint(JavaFieldBreakpointType.class, breakpointNode);
434 else if (category.equals(ExceptionBreakpoint.CATEGORY.toString())) {
435 xBreakpoint = createXBreakpoint(JavaExceptionBreakpointType.class);
437 if (xBreakpoint == null) {
438 throw new IllegalStateException("Unknown breakpoint category " + category);
440 return getJavaBreakpoint(xBreakpoint);
443 private <B extends XBreakpoint<?>> XBreakpoint createXBreakpoint(Class<? extends XBreakpointType<B, ?>> typeCls) {
444 final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
445 return ApplicationManager.getApplication().runWriteAction((Computable<XBreakpoint>)() -> XDebuggerManager.getInstance(myProject).getBreakpointManager().addBreakpoint((XBreakpointType)type, type.createProperties()));
448 private <B extends XBreakpoint<?>> XLineBreakpoint createXLineBreakpoint(Class<? extends XBreakpointType<B, ?>> typeCls,
449 Element breakpointNode) throws InvalidDataException {
450 final String url = breakpointNode.getAttributeValue("url");
451 VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(url);
453 throw new InvalidDataException(DebuggerBundle.message("error.breakpoint.file.not.found", url));
455 final Document doc = FileDocumentManager.getInstance().getDocument(vFile);
457 throw new InvalidDataException(DebuggerBundle.message("error.cannot.load.breakpoint.file", url));
462 //noinspection HardCodedStringLiteral
463 line = Integer.parseInt(breakpointNode.getAttributeValue("line"));
465 catch (Exception e) {
466 throw new InvalidDataException("Line number is invalid for breakpoint");
468 return addXLineBreakpoint(typeCls, doc, line);
471 public static void addBreakpoint(@NotNull Breakpoint breakpoint) {
472 assert breakpoint.myXBreakpoint.getUserData(Breakpoint.DATA_KEY) == breakpoint;
473 breakpoint.updateUI();
474 checkAndNotifyPossiblySlowBreakpoint(breakpoint.myXBreakpoint);
477 public void removeBreakpoint(@Nullable final Breakpoint breakpoint) {
478 if (breakpoint == null) {
481 ApplicationManager.getApplication().runWriteAction(() -> getXBreakpointManager().removeBreakpoint(breakpoint.myXBreakpoint));
484 public void writeExternal(@NotNull final Element parentNode) {
485 // restore old breakpoints
486 for (Element group : myOriginalBreakpointsNodes.values()) {
487 if (group.getAttribute(CONVERTED_PARAM) == null) {
488 group.setAttribute(CONVERTED_PARAM, "true");
490 parentNode.addContent(group.clone());
495 public List<Breakpoint> getBreakpoints() {
496 return ApplicationManager.getApplication().runReadAction((Computable<List<Breakpoint>>)() ->
497 ContainerUtil.mapNotNull(getXBreakpointManager().getAllBreakpoints(), BreakpointManager::getJavaBreakpoint));
501 public static Breakpoint getJavaBreakpoint(@Nullable final XBreakpoint xBreakpoint) {
502 if (xBreakpoint == null) {
505 Breakpoint breakpoint = xBreakpoint.getUserData(Breakpoint.DATA_KEY);
506 if (breakpoint == null && xBreakpoint.getType() instanceof JavaBreakpointType) {
507 Project project = ((XBreakpointBase)xBreakpoint).getProject();
508 breakpoint = ((JavaBreakpointType)xBreakpoint.getType()).createJavaBreakpoint(project, xBreakpoint);
509 xBreakpoint.putUserData(Breakpoint.DATA_KEY, breakpoint);
514 //interaction with RequestManagerImpl
515 public void disableBreakpoints(@NotNull final DebugProcessImpl debugProcess) {
516 final List<Breakpoint> breakpoints = getBreakpoints();
517 if (!breakpoints.isEmpty()) {
518 final RequestManagerImpl requestManager = debugProcess.getRequestsManager();
519 for (Breakpoint breakpoint : breakpoints) {
520 breakpoint.markVerified(requestManager.isVerified(breakpoint));
521 requestManager.deleteRequest(breakpoint);
523 SwingUtilities.invokeLater(this::updateBreakpointsUI);
527 public void enableBreakpoints(final DebugProcessImpl debugProcess) {
528 final List<Breakpoint> breakpoints = getBreakpoints();
529 if (!breakpoints.isEmpty()) {
530 for (Breakpoint breakpoint : breakpoints) {
531 breakpoint.markVerified(false); // clean cached state
532 breakpoint.createRequest(debugProcess);
534 SwingUtilities.invokeLater(this::updateBreakpointsUI);
538 public void applyThreadFilter(@NotNull final DebugProcessImpl debugProcess, @Nullable ThreadReference newFilterThread) {
539 final RequestManagerImpl requestManager = debugProcess.getRequestsManager();
540 final ThreadReference oldFilterThread = requestManager.getFilterThread();
541 if (Comparing.equal(newFilterThread, oldFilterThread)) {
542 // the filter already added
545 requestManager.setFilterThread(newFilterThread);
546 if (newFilterThread == null || oldFilterThread != null) {
547 final List<Breakpoint> breakpoints = getBreakpoints();
548 for (Breakpoint breakpoint : breakpoints) {
549 if (LineBreakpoint.CATEGORY.equals(breakpoint.getCategory()) || MethodBreakpoint.CATEGORY.equals(breakpoint.getCategory())) {
550 requestManager.deleteRequest(breakpoint);
551 breakpoint.createRequest(debugProcess);
556 // important! need to add filter to _existing_ requests, otherwise Requestor->Request mapping will be lost
557 // and debugger trees will not be restored to original state
558 abstract class FilterSetter <T extends EventRequest> {
559 void applyFilter(@NotNull final List<T> requests, final ThreadReference thread) {
560 for (T request : requests) {
562 final boolean wasEnabled = request.isEnabled();
566 addFilter(request, thread);
571 catch (InternalException e) {
574 catch (InvalidRequestStateException e) {
579 protected abstract void addFilter(final T request, final ThreadReference thread);
582 final EventRequestManager eventRequestManager = requestManager.getVMRequestManager();
583 if (eventRequestManager != null) {
584 new FilterSetter<BreakpointRequest>() {
586 protected void addFilter(@NotNull final BreakpointRequest request, final ThreadReference thread) {
587 request.addThreadFilter(thread);
589 }.applyFilter(eventRequestManager.breakpointRequests(), newFilterThread);
591 new FilterSetter<MethodEntryRequest>() {
593 protected void addFilter(@NotNull final MethodEntryRequest request, final ThreadReference thread) {
594 request.addThreadFilter(thread);
596 }.applyFilter(eventRequestManager.methodEntryRequests(), newFilterThread);
598 new FilterSetter<MethodExitRequest>() {
600 protected void addFilter(@NotNull final MethodExitRequest request, final ThreadReference thread) {
601 request.addThreadFilter(thread);
603 }.applyFilter(eventRequestManager.methodExitRequests(), newFilterThread);
608 public void updateBreakpointsUI() {
609 ApplicationManager.getApplication().assertIsDispatchThread();
610 getBreakpoints().forEach(Breakpoint::updateUI);
613 public void reloadBreakpoints() {
614 ApplicationManager.getApplication().assertIsDispatchThread();
615 getBreakpoints().forEach(Breakpoint::reload);
618 public void fireBreakpointChanged(Breakpoint breakpoint) {
620 breakpoint.updateUI();
623 public void setBreakpointEnabled(@NotNull final Breakpoint breakpoint, final boolean enabled) {
624 if (breakpoint.isEnabled() != enabled) {
625 breakpoint.setEnabled(enabled);
630 public Breakpoint findMasterBreakpoint(@NotNull Breakpoint dependentBreakpoint) {
631 XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager();
632 return getJavaBreakpoint(dependentBreakpointManager.getMasterBreakpoint(dependentBreakpoint.myXBreakpoint));
635 public String getProperty(String name) {
636 return myUIProperties.get(name);
639 public String setProperty(String name, String value) {
640 return myUIProperties.put(name, value);