From 001c155dac3e3bbd0ee508b80d099f8cddff50d2 Mon Sep 17 00:00:00 2001 From: Dmytro Nochevnov Date: Tue, 1 Mar 2016 18:48:22 +0200 Subject: [PATCH] CHE-201: remove breakpoints in case of absence of linked file Remove all debugger breakpoints and current execution point in the next cases: case 1: when linked file has been removed from project explorer; case 2: when folder with linked file has been removed from project explorer; case 3: when project with linked file has been removed from project explorer; case 4: when there is no project with linked file after the loading of project explorer. Signed-off-by: Dmytro Nochevnov --- .../che/ide/debug/DebuggerManager.java | 19 +-- .../project/ProjectExplorerViewImpl.java | 4 + core/ide/che-core-ide-jseditor/pom.xml | 4 + .../client/debug/BreakpointManagerImpl.java | 152 +++++++++++++++--- 4 files changed, 142 insertions(+), 37 deletions(-) diff --git a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/debug/DebuggerManager.java b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/debug/DebuggerManager.java index 0e6203a46d..1d0fa35b6a 100644 --- a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/debug/DebuggerManager.java +++ b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/debug/DebuggerManager.java @@ -15,7 +15,6 @@ import com.google.inject.Singleton; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.api.app.AppContext; -import org.eclipse.che.ide.api.app.CurrentProject; import java.util.HashMap; import java.util.Map; @@ -31,6 +30,7 @@ public class DebuggerManager { private final AppContext appContext; private Map debuggers; + private Debugger debugger; @Inject protected DebuggerManager(AppContext appContext) { @@ -40,25 +40,22 @@ public class DebuggerManager { /** * Register new debugger for the specified project type ID. + * TODO: don't link debugger with project. * * @param projectTypeId * @param debugger */ public void registeredDebugger(String projectTypeId, Debugger debugger) { debuggers.put(projectTypeId, debugger); + setDebugger(debugger); + } + + public void setDebugger(Debugger debugger) { + this.debugger = debugger; } - /** - * @return debugger for current project type or null otherwise - */ @Nullable public Debugger getDebugger() { - CurrentProject currentProject = appContext.getCurrentProject(); - if (currentProject != null) { - String projectTypeId = currentProject.getProjectConfig().getType(); - return debuggers.get(projectTypeId); - } - - return null; + return debugger; } } \ No newline at end of file diff --git a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java index 201e652239..30b5d0f7d4 100644 --- a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java +++ b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerViewImpl.java @@ -270,6 +270,10 @@ public class ProjectExplorerViewImpl extends BaseViewjavax.validation validation-api + + org.eclipse.che.core + che-core-api-workspace + org.eclipse.che.core che-core-commons-annotations diff --git a/core/ide/che-core-ide-jseditor/src/main/java/org/eclipse/che/ide/jseditor/client/debug/BreakpointManagerImpl.java b/core/ide/che-core-ide-jseditor/src/main/java/org/eclipse/che/ide/jseditor/client/debug/BreakpointManagerImpl.java index 08c817ed38..fa46a67254 100644 --- a/core/ide/che-core-ide-jseditor/src/main/java/org/eclipse/che/ide/jseditor/client/debug/BreakpointManagerImpl.java +++ b/core/ide/che-core-ide-jseditor/src/main/java/org/eclipse/che/ide/jseditor/client/debug/BreakpointManagerImpl.java @@ -14,12 +14,16 @@ import com.google.gwt.storage.client.Storage; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.web.bindery.event.shared.EventBus; +import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.api.editor.EditorAgent; import org.eclipse.che.ide.api.editor.EditorOpenedEvent; import org.eclipse.che.ide.api.editor.EditorOpenedEventHandler; import org.eclipse.che.ide.api.editor.EditorPartPresenter; +import org.eclipse.che.ide.api.event.project.DeleteProjectEvent; +import org.eclipse.che.ide.api.event.project.DeleteProjectHandler; import org.eclipse.che.ide.api.project.node.HasProjectConfig.ProjectConfig; +import org.eclipse.che.ide.api.project.node.Node; import org.eclipse.che.ide.api.project.tree.VirtualFile; import org.eclipse.che.ide.api.project.tree.VirtualFileImpl; import org.eclipse.che.ide.api.project.tree.VirtualFileInfo; @@ -40,17 +44,25 @@ import org.eclipse.che.ide.debug.dto.BreakpointDto; import org.eclipse.che.ide.dto.DtoFactory; import org.eclipse.che.ide.jseditor.client.document.Document; import org.eclipse.che.ide.jseditor.client.texteditor.EmbeddedTextEditorPresenter; +import org.eclipse.che.ide.project.event.ProjectExplorerLoadedEvent; +import org.eclipse.che.ide.project.event.ResourceNodeDeletedEvent; +import org.eclipse.che.ide.project.node.FileReferenceNode; +import org.eclipse.che.ide.project.node.FolderReferenceNode; +import org.eclipse.che.ide.project.node.ItemReferenceBasedNode; +import org.eclipse.che.ide.project.node.ResourceBasedNode; import javax.inject.Inject; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.logging.Logger; -import static org.eclipse.che.ide.debug.DebuggerState.CONNECTED; import static org.eclipse.che.ide.debug.DebuggerState.DISCONNECTED; /** @@ -58,6 +70,7 @@ import static org.eclipse.che.ide.debug.DebuggerState.DISCONNECTED; * * @author Anatoliy Bazko * @author Valeriy Svydenko + * @author Dmytro Nochevnov */ public class BreakpointManagerImpl implements BreakpointManager, LineChangeAction { @@ -129,7 +142,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio private void deleteBreakpoint(final VirtualFile activeFile, final Debugger debugger, final Breakpoint breakpoint) { - doDeleteBreakpoint(activeFile, breakpoint); + doDeleteBreakpoint(breakpoint); debugger.deleteBreakpoint(activeFile, breakpoint.getLineNumber(), new AsyncCallback() { @Override @@ -138,18 +151,30 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio @Override public void onFailure(final Throwable exception) { - if (debuggerState == CONNECTED) { - doAddBreakpoint(activeFile, breakpoint); - } } }); } + /** + * Deletes breakpoints linked to paths from the list and JVM. + * Removes breakpoints' marks. + */ + private void deleteBreakpoints(final Set paths) { + for (String path : paths) { + List breakpointsToDelete = this.breakpoints.get(path); + if (breakpointsToDelete != null) { + for (Breakpoint breakpoint : new ArrayList(breakpointsToDelete)) { + deleteBreakpoint(breakpoint.getFile(), debuggerManager.getDebugger(), breakpoint); + } + } + } + } + /** * Deletes breakpoint from the list. */ - private void doDeleteBreakpoint(VirtualFile activeFile, Breakpoint breakpoint) { - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(activeFile); + private void doDeleteBreakpoint(Breakpoint breakpoint) { + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getPath()); if (breakpointRenderer != null) { breakpointRenderer.removeBreakpointMark(breakpoint.getLineNumber()); } @@ -160,7 +185,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio if (fileBreakpoints != null) { fileBreakpoints.remove(breakpoint); if (fileBreakpoints.isEmpty()) { - breakpoints.remove(activeFile.getPath()); + breakpoints.remove(breakpoint.getPath()); } } @@ -207,7 +232,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio fileBreakpoints.add(breakpoint); - final BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(activeFile); + final BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(activeFile.getPath()); if (breakpointRenderer != null) { breakpointRenderer.addBreakpointMark(breakpoint.getLineNumber(), new LineChangeAction() { @Override @@ -225,7 +250,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio * Indicates if line of code to add breakpoint at is executable. */ private boolean isCodeExecutable(final VirtualFile activeFile, int lineNumber) { - EditorPartPresenter editor = getEditorForFile(activeFile); + EditorPartPresenter editor = getEditorForFile(activeFile.getPath()); if (editor instanceof EmbeddedTextEditorPresenter) { Document document = ((EmbeddedTextEditorPresenter)editor).getDocument(); return !document.getLineContent(lineNumber).trim().isEmpty(); @@ -253,7 +278,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio private void removeBreakpointsForPath(final String path, final List pathBreakpoints) { LOG.fine("\tRemove all breakpoints for path " + path); for (final Breakpoint breakpoint : pathBreakpoints) { - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getFile()); + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getPath()); if (breakpointRenderer != null) { breakpointRenderer.removeBreakpointMark(breakpoint.getLineNumber()); } @@ -291,7 +316,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio private void doSetCurrentBreakpoint(VirtualFile activeFile, int lineNumber) { currentBreakpoint = new Breakpoint(Type.CURRENT, lineNumber, activeFile.getPath(), activeFile, true); - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(activeFile); + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(activeFile.getPath()); if (breakpointRenderer != null) { breakpointRenderer.setLineActive(lineNumber, true); } @@ -312,7 +337,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio if (currentBreakpoint != null) { int oldLineNumber = currentBreakpoint.getLineNumber(); LOG.fine("Unmark current breakpoint on line " + oldLineNumber); - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(currentBreakpoint.getFile()); + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(currentBreakpoint.getPath()); if (breakpointRenderer != null) { breakpointRenderer.setLineActive(oldLineNumber, false); } @@ -336,11 +361,11 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio } @Nullable - private EditorPartPresenter getEditorForFile(VirtualFile fileNode) { + private EditorPartPresenter getEditorForFile(String path) { final Map openedEditors = editorAgent.getOpenedEditors(); for (final String key : openedEditors.keySet()) { final EditorPartPresenter editor = openedEditors.get(key); - if (fileNode.getPath().equals(editor.getEditorInput().getFile().getPath())) { + if (path.equals(editor.getEditorInput().getFile().getPath())) { return editor; } } @@ -348,8 +373,8 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio } @Nullable - private BreakpointRenderer getBreakpointRendererForFile(VirtualFile fileNode) { - final EditorPartPresenter editor = getEditorForFile(fileNode); + private BreakpointRenderer getBreakpointRendererForFile(String path) { + final EditorPartPresenter editor = getEditorForFile(path); if (editor != null) { return getBreakpointRendererForEditor(editor); } else { @@ -421,7 +446,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio eventBus.addHandler(EditorOpenedEvent.TYPE, new EditorOpenedEventHandler() { @Override public void onEditorOpened(EditorOpenedEvent event) { - onOpenEditor(event.getFile(), event.getEditor()); + onOpenEditor(event.getFile().getPath(), event.getEditor()); } }); @@ -445,6 +470,81 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio onBreakpointStateChanged(event.getState(), event.getFilePath(), event.getLineNumber()); } }); + + eventBus.addHandler(DeleteProjectEvent.TYPE, new DeleteProjectHandler() { + @Override + public void onProjectDeleted(DeleteProjectEvent event) { + if (breakpoints.isEmpty()) { + return; + } + + ProjectConfigDto config = event.getProjectConfig(); + String path = config.getPath() + "/"; + deleteBreakpoints(getBreakpointsForPath(path)); + } + }); + + eventBus.addHandler(ResourceNodeDeletedEvent.getType(), new ResourceNodeDeletedEvent.ResourceNodeDeletedHandler() { + @Override + public void onResourceEvent(ResourceNodeDeletedEvent event) { + if (breakpoints.isEmpty()) { + return; + } + + ResourceBasedNode node = event.getNode(); + if (node instanceof ItemReferenceBasedNode) { + String path = ((ItemReferenceBasedNode)node).getStorablePath(); + + if (node instanceof FolderReferenceNode) { + path += "/"; + deleteBreakpoints(getBreakpointsForPath(path)); + + } else if (node instanceof FileReferenceNode) { + deleteBreakpoints(Collections.singleton(path)); + } + } + } + }); + + eventBus.addHandler(ProjectExplorerLoadedEvent.getType(), new ProjectExplorerLoadedEvent.ProjectExplorerLoadedHandler() { + @Override + public void onProjectsLoaded(ProjectExplorerLoadedEvent event) { + if (breakpoints.isEmpty()) { + return; + } + + // remove breakpoints which refer to un-existed projects + List projects = event.getNodes(); + Set pathsToDelete = new HashSet(breakpoints.keySet()); + + for (String breakpointPath : breakpoints.keySet()) { + for (Node project : projects) { + String projectName = project.getName(); + if (breakpointPath.startsWith("/" + projectName + "/")) { + pathsToDelete.remove(breakpointPath); + break; + } + } + } + + deleteBreakpoints(pathsToDelete); + } + }); + } + + /** + * @returns pathToFind examples: "/test-spring/", "/test-spring/src/", "/test-spring/src/main/java/Test.java" + */ + private Set getBreakpointsForPath(String pathToFind) { + Set foundPaths = new HashSet<>(breakpoints.size()); + for (Entry> breakpointsForPath : breakpoints.entrySet()) { + String path = breakpointsForPath.getKey(); + if (path.startsWith(pathToFind)) { + foundPaths.add(path); + } + } + + return foundPaths; } /** @@ -469,7 +569,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio true); breakpointsForPath.set(i, newActiveBreakpoint); - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getFile()); + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getPath()); if (breakpointRenderer != null) { breakpointRenderer.setBreakpointActive(breakpoint.getLineNumber(), true); } @@ -532,7 +632,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio false); breakpointsForPath.set(i, newInactiveBreakpoint); - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getFile()); + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getPath()); if (breakpointRenderer != null) { breakpointRenderer.setBreakpointActive(breakpoint.getLineNumber(), false); } @@ -566,7 +666,7 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio true); breakpointsForPath.set(breakpointNumber, newActiveBreakpoint); - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getFile()); + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(breakpoint.getPath()); if (breakpointRenderer != null) { breakpointRenderer.setBreakpointActive(breakpoint.getLineNumber(), true); } @@ -582,10 +682,10 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio /** * The new file has been opened in the editor. - * Method readds breakpoints. + * Method reads breakpoints. */ - private void onOpenEditor(VirtualFile file, EditorPartPresenter editor) { - final List fileBreakpoints = breakpoints.get(file.getPath()); + private void onOpenEditor(String path, EditorPartPresenter editor) { + final List fileBreakpoints = breakpoints.get(path); if (fileBreakpoints != null) { final BreakpointRenderer breakpointRenderer = getBreakpointRendererForEditor(editor); @@ -597,8 +697,8 @@ public class BreakpointManagerImpl implements BreakpointManager, LineChangeActio } } - if (currentBreakpoint != null && file.getPath().equals(currentBreakpoint.getPath())) { - BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(file); + if (currentBreakpoint != null && path.equals(currentBreakpoint.getPath())) { + BreakpointRenderer breakpointRenderer = getBreakpointRendererForFile(path); if (breakpointRenderer != null) { breakpointRenderer.setLineActive(currentBreakpoint.getLineNumber(), true); }