Skip to content

Commit 5054900

Browse files
fix: use project path as cache root and display issues on right node (#230)
* fix: use project cache as cache root * chore: remove unneeded issue cache init * fix: use right cache for product nodes * fix: a test * fix: tests * chore: improve code a bit * fix: refresh treeview when new nodes were added * chore: remove obsolete code * chore: remove logging * chore: remove logging
1 parent 09e18b7 commit 5054900

12 files changed

Lines changed: 214 additions & 116 deletions

File tree

plugin/src/main/java/io/snyk/eclipse/plugin/utils/ResourceUtils.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import java.nio.file.Path;
77
import java.util.Base64;
88

9+
import org.eclipse.core.resources.IProject;
910
import org.eclipse.core.resources.IResource;
11+
import org.eclipse.core.resources.ResourcesPlugin;
1012
import org.eclipse.core.runtime.FileLocator;
1113
import org.osgi.framework.Bundle;
1214

@@ -46,4 +48,15 @@ private static byte[] getImageDataFromUrl(URL imageUrl) {
4648
public static Path getFullPath(IResource resource) {
4749
return resource.getLocation().toPath().toAbsolutePath();
4850
}
51+
52+
public static IProject getProjectByPath(Path path) {
53+
var projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
54+
for (IProject iProject : projects) {
55+
Path projectPath = ResourceUtils.getFullPath(iProject);
56+
if (iProject.isAccessible() && path.normalize().startsWith(projectPath)) {
57+
return iProject;
58+
}
59+
}
60+
return null;
61+
}
4962
}

plugin/src/main/java/io/snyk/eclipse/plugin/utils/SnykLogger.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,29 @@
55
import org.eclipse.ui.PlatformUI;
66
import org.eclipse.ui.statushandlers.StatusManager;
77

8+
import io.snyk.eclipse.plugin.Activator;
9+
import io.snyk.eclipse.plugin.SnykStartup;
10+
import io.snyk.languageserver.SnykLanguageServer;
11+
812
public class SnykLogger {
913

10-
public static void logError(Exception exception) {
11-
Status status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, "Snyk plugin: " + exception.getMessage(), exception);
14+
public static void logError(Exception exception) {
15+
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, exception.getMessage(),
16+
exception);
17+
18+
StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG);
19+
}
20+
21+
public static void logInfo(String message) {
22+
Status status = new Status(IStatus.INFO, Activator.PLUGIN_ID, message);
23+
24+
StatusManager.getManager().handle(status, StatusManager.LOG);
25+
}
26+
27+
public static void logAndShow(String message) {
28+
Status status = new Status(IStatus.INFO, Activator.PLUGIN_ID, message);
1229

13-
StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG);
14-
}
15-
16-
public static void logInfo(String message) {
17-
Status status = new Status(IStatus.INFO, PlatformUI.PLUGIN_ID, "Snyk plugin: " + message);
30+
StatusManager.getManager().handle(status, StatusManager.LOG | StatusManager.SHOW);
31+
}
1832

19-
StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG);
20-
}
2133
}

plugin/src/main/java/io/snyk/eclipse/plugin/views/snyktoolview/BaseTreeNode.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,21 @@ public void addChild(BaseTreeNode child) {
3131

3232
list = new ArrayList<BaseTreeNode>(previousList);
3333
}
34+
child.setParent(this);
3435
list.add(child);
3536
this.setChildren(list.toArray(new BaseTreeNode[list.size()]));
3637
}
3738

3839
public void removeChildren() {
40+
TreeNode[] children = this.getChildren();
41+
if (children == null) {
42+
return;
43+
}
44+
45+
for (TreeNode child : children) {
46+
child.setParent(null);
47+
}
48+
3949
setChildren(new BaseTreeNode[0]);
4050
}
4151

@@ -66,9 +76,10 @@ public void reset() {
6676
this.value = null;
6777
this.imageDescriptor = null;
6878
}
69-
79+
7080
/**
7181
* Provides the details to be displayed in the details view
82+
*
7283
* @return html details
7384
*/
7485
public String getDetails() {

plugin/src/main/java/io/snyk/eclipse/plugin/views/snyktoolview/ContentRootNode.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77

88
import java.nio.file.Path;
99

10-
import org.eclipse.core.resources.ResourcesPlugin;
1110
import org.eclipse.jface.resource.ImageDescriptor;
11+
import org.eclipse.jface.viewers.ILabelProvider;
1212
import org.eclipse.swt.graphics.Image;
1313
import org.eclipse.ui.model.WorkbenchLabelProvider;
1414

1515
import io.snyk.eclipse.plugin.domain.ProductConstants;
16+
import io.snyk.eclipse.plugin.utils.ResourceUtils;
17+
import io.snyk.eclipse.plugin.utils.SnykLogger;
1618

1719
public class ContentRootNode extends BaseTreeNode {
1820
private Path path;
@@ -27,11 +29,11 @@ public ContentRootNode(String name, Path value) {
2729

2830
@Override
2931
public ImageDescriptor getImageDescriptor() {
30-
WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();
32+
ILabelProvider labelProvider = WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider();
3133
try {
32-
var object = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
34+
var object = ResourceUtils.getProjectByPath(path);
3335
Image image = labelProvider.getImage(object);
34-
if (image == null)
36+
if (image == null || image.isDisposed())
3537
return null;
3638

3739
return ImageDescriptor.createFromImage(image);
@@ -71,7 +73,8 @@ public void reset() {
7173
var iacRootNode = new ProductTreeNode(DISPLAYED_IAC);
7274
iacRootNode.setParent(this);
7375

74-
ProductTreeNode[] productNodes = new ProductTreeNode[] { ossRootNode, codeSecurityRootNode, codeQualityRootNode, iacRootNode, };
76+
ProductTreeNode[] productNodes = new ProductTreeNode[] { ossRootNode, codeSecurityRootNode, codeQualityRootNode,
77+
iacRootNode, };
7578
this.setChildren(productNodes);
7679
}
7780

@@ -85,6 +88,9 @@ public Path getPath() {
8588
}
8689

8790
public void setPath(Path path) {
88-
this.path = path;
91+
if (!path.toString().endsWith(this.name)) {
92+
throw new IllegalArgumentException(value + " does not end with " + name);
93+
}
94+
this.path = path.normalize();
8995
}
9096
}

plugin/src/main/java/io/snyk/eclipse/plugin/views/snyktoolview/FileTreeNode.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,25 @@
55

66
import org.eclipse.core.resources.ResourcesPlugin;
77
import org.eclipse.jface.resource.ImageDescriptor;
8+
import org.eclipse.jface.viewers.ILabelProvider;
9+
import org.eclipse.jface.viewers.TreeNode;
810
import org.eclipse.swt.graphics.Image;
911
import org.eclipse.ui.model.WorkbenchLabelProvider;
1012

13+
import io.snyk.eclipse.plugin.utils.SnykLogger;
14+
1115
public class FileTreeNode extends BaseTreeNode {
1216
private Path path;
1317

1418
public FileTreeNode(String value) {
1519
super(value);
1620
this.setPath(Paths.get(value));
21+
this.setText(value);
1722
}
1823

1924
@Override
2025
public ImageDescriptor getImageDescriptor() {
21-
// TODO: this does not display the file icon. Why?
22-
WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();
26+
ILabelProvider labelProvider = WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider();
2327
try {
2428
var files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(getPath().toUri());
2529
var object = files[0];
@@ -29,7 +33,7 @@ public ImageDescriptor getImageDescriptor() {
2933
Image image = labelProvider.getImage(object);
3034
if (image == null)
3135
return null;
32-
36+
3337
return ImageDescriptor.createFromImage(image);
3438
} finally {
3539
labelProvider.dispose();
@@ -38,17 +42,26 @@ public ImageDescriptor getImageDescriptor() {
3842

3943
@Override
4044
public String getText() {
41-
// TODO Auto-generated method stub
42-
return super.getText();
45+
return getPath().toString();
4346
}
4447

4548
public Path getPath() {
4649
return path;
4750
}
4851

4952
public void setPath(Path path) {
50-
this.path = path;
53+
this.path = path.normalize();
54+
}
55+
56+
@Override
57+
public void setParent(TreeNode parent) {
58+
if (!(parent instanceof ProductTreeNode))
59+
throw new IllegalArgumentException(
60+
parent.getClass().getName() + " cannot be a parent node to a FileTreeNode");
61+
var crNode = (ContentRootNode) parent.getParent();
62+
if (!this.getPath().startsWith(crNode.getPath()))
63+
throw new IllegalArgumentException(crNode.getPath() + " is not a sub path of " + this.getPath());
64+
super.setParent(parent);
5165
}
52-
53-
66+
5467
}

plugin/src/main/java/io/snyk/eclipse/plugin/views/snyktoolview/ProductTreeNode.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
import java.util.Arrays;
55
import java.util.HashSet;
66

7-
import org.eclipse.jface.resource.ImageDescriptor;
87
import org.eclipse.jface.viewers.TreeNode;
98

10-
import io.snyk.eclipse.plugin.Activator;
119
import io.snyk.eclipse.plugin.domain.ProductConstants;
1210
import io.snyk.eclipse.plugin.utils.SnykIcons;
11+
import io.snyk.eclipse.plugin.utils.SnykLogger;
1312

1413
public class ProductTreeNode extends BaseTreeNode {
1514

@@ -74,6 +73,20 @@ public void setValue(Object value) {
7473
super.setValue(cleanedValue);
7574
}
7675

76+
@Override
77+
public void addChild(BaseTreeNode child) {
78+
if (child instanceof FileTreeNode) {
79+
var ftNode = (FileTreeNode) child;
80+
var crNode = (ContentRootNode) this.getParent();
81+
if (!ftNode.getPath().startsWith(crNode.getPath())) {
82+
throw new IllegalArgumentException(
83+
ftNode.getPath().toString() + " is not a sub path of " + crNode.getPath().toString());
84+
}
85+
}
86+
87+
super.addChild(child);
88+
}
89+
7790
private String removePrefix(String value) {
7891
var cleanedValue = value.toString();
7992
cleanedValue = cleanedValue.replace(product, "");

plugin/src/main/java/io/snyk/eclipse/plugin/views/snyktoolview/SnykToolView.java

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package io.snyk.eclipse.plugin.views.snyktoolview;
22

3+
import java.nio.file.Path;
34
import java.nio.file.Paths;
45

5-
import org.eclipse.core.runtime.Platform;
66
import org.eclipse.jface.action.IMenuManager;
77
import org.eclipse.jface.action.MenuManager;
88
import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -11,33 +11,24 @@
1111
import org.eclipse.jface.viewers.TreeNode;
1212
import org.eclipse.jface.viewers.TreeViewer;
1313
import org.eclipse.lsp4e.LSPEclipseUtils;
14-
import org.eclipse.lsp4j.Location;
15-
import org.eclipse.lsp4j.Position;
16-
import org.eclipse.lsp4j.Range;
1714
import org.eclipse.swt.SWT;
1815
import org.eclipse.swt.browser.Browser;
19-
import org.eclipse.swt.browser.BrowserFunction;
20-
import org.eclipse.swt.browser.LocationEvent;
21-
import org.eclipse.swt.browser.LocationListener;
2216
import org.eclipse.swt.custom.SashForm;
2317
import org.eclipse.swt.layout.FillLayout;
2418
import org.eclipse.swt.layout.GridData;
2519
import org.eclipse.swt.layout.GridLayout;
26-
import org.eclipse.swt.program.Program;
2720
import org.eclipse.swt.widgets.Composite;
2821
import org.eclipse.swt.widgets.Display;
2922
import org.eclipse.swt.widgets.Menu;
30-
import org.eclipse.swt.widgets.Shell;
3123
import org.eclipse.swt.widgets.Tree;
3224
import org.eclipse.ui.PlatformUI;
3325
import org.eclipse.ui.menus.CommandContributionItem;
3426
import org.eclipse.ui.menus.CommandContributionItemParameter;
3527
import org.eclipse.ui.part.ViewPart;
36-
import org.osgi.framework.Bundle;
3728

38-
import io.snyk.eclipse.plugin.html.HtmlProviderFactory;
3929
import io.snyk.eclipse.plugin.properties.preferences.Preferences;
4030
import io.snyk.eclipse.plugin.utils.ResourceUtils;
31+
import io.snyk.eclipse.plugin.utils.SnykLogger;
4132
import io.snyk.eclipse.plugin.views.snyktoolview.providers.TreeContentProvider;
4233
import io.snyk.eclipse.plugin.views.snyktoolview.providers.TreeLabelProvider;
4334

@@ -57,9 +48,7 @@ public class SnykToolView extends ViewPart implements ISnykToolView {
5748

5849
private TreeViewer treeViewer;
5950
private Browser browser;
60-
private BaseTreeNode rootObject = new RootNode();
6151
private BrowserHandler browserHandler;
62-
private final static Shell SHELL = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
6352

6453
@Override
6554
public void createPartControl(Composite parent) {
@@ -79,7 +68,7 @@ public void createPartControl(Composite parent) {
7968
treeViewer.setLabelProvider(new TreeLabelProvider());
8069

8170
// Create and set the root object
82-
treeViewer.setInput(rootObject);
71+
treeViewer.setInput(new RootNode());
8372
treeViewer.expandAll();
8473

8574
registerTreeContextMeny(parent);
@@ -99,17 +88,19 @@ public void createPartControl(Composite parent) {
9988
public void selectionChanged(SelectionChangedEvent event) {
10089
Display.getDefault().asyncExec(() -> {
10190
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
102-
if (selection.isEmpty()) return;
91+
if (selection.isEmpty())
92+
return;
10393
TreeNode node = (TreeNode) selection.getFirstElement();
10494
browserHandler.updateBrowserContent(node);
10595
if (node instanceof IssueTreeNode) {
10696
IssueTreeNode issueTreeNode = (IssueTreeNode) node;
10797
FileTreeNode fileNode = (FileTreeNode) issueTreeNode.getParent();
10898
LSPEclipseUtils.open(fileNode.getPath().toUri().toASCIIString(),
10999
issueTreeNode.getIssue().getLSP4JRange());
110-
}
111-
});
112-
}});
100+
}
101+
});
102+
}
103+
});
113104
}
114105

115106
private void registerTreeContextMeny(Composite parent) {
@@ -168,10 +159,13 @@ public ProductTreeNode getProductNode(String product, String folderPath) {
168159
return null;
169160
}
170161

171-
for (TreeNode child : rootObject.getChildren()) {
162+
for (TreeNode child : getRoot().getChildren()) {
172163
if (child instanceof ContentRootNode) {
173164
ContentRootNode contentRoot = (ContentRootNode) child;
174165
var givenPath = Paths.get(folderPath);
166+
if (contentRoot.getPath().toString().isBlank()) {
167+
throw new RuntimeException("unexpected blank content root node " + child);
168+
}
175169
if (givenPath.startsWith(contentRoot.getPath())) {
176170
return contentRoot.getProductNode(product);
177171
}
@@ -182,7 +176,7 @@ public ProductTreeNode getProductNode(String product, String folderPath) {
182176

183177
@Override
184178
public BaseTreeNode getRoot() {
185-
return this.rootObject;
179+
return ((RootNode) treeViewer.getInput());
186180
}
187181

188182
@Override
@@ -219,9 +213,9 @@ public void clearTree() {
219213
}
220214

221215
private void clearRoot() {
222-
if (this.rootObject != null) {
223-
this.rootObject.removeChildren();
224-
this.rootObject.reset();
216+
var root = getRoot();
217+
if (root != null) {
218+
root.reset();
225219
}
226220
}
227221

0 commit comments

Comments
 (0)