Skip to content

Commit 4a658cd

Browse files
bastiandoetschackeShawkyZ
authored
feat: populate tree [IDE-712] (#218)
* feat: add project level * fix: tests * feat: add file & issue nodes (wip) * feat: add issue navigation * fix: add missing icons * fix: node filtering * fix: create custom publishDiagnostic for faster deserilization * fix: use Webview2 browser on Windows * chore: added comment * wip: cancel all scans * tidy: clean up unused things * fix: clean up tree when scan is cancelled * fix: expand treenodes after product nodes are added to tree * fix: added unit tests for progressmanager * fix: indentation * fix: dont run progress cancellation in UI --------- Co-authored-by: Knut Funkel <knut.funkel@snyk.io> Co-authored-by: Abdelrahman Shawki Hassan <shawki.hassan@snyk.io>
1 parent a39a67e commit 4a658cd

23 files changed

Lines changed: 915 additions & 244 deletions

File tree

plugin/src/main/java/io/snyk/eclipse/plugin/domain/ProductConstants.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,18 @@ public interface ProductConstants {
1313

1414
String DIAGNOSTIC_SOURCE_SNYK_OSS = "Snyk Open Source";
1515
String DIAGNOSTIC_SOURCE_SNYK_CODE = "Snyk Code";
16-
String DIAGNOSTIC_SOURCE_SNYK_IAC = "Snyk Infrastructure";
16+
String DIAGNOSTIC_SOURCE_SNYK_IAC = "Snyk IaC";
1717

1818
String DISPLAYED_OSS = "Snyk Open Source";
1919
String DISPLAYED_CODE_SECURITY = "Code Security";
2020
String DISPLAYED_CODE_QUALITY = "Code Quality";
2121
String DISPLAYED_IAC = "Configuration";
2222

23+
String SEVERITY_CRITICAL = "critical";
24+
String SEVERITY_HIGH = "high";
25+
String SEVERITY_MEDIUM = "medium";
26+
String SEVERITY_LOW = "low";
27+
2328
Map<String, String> LSP_SOURCE_TO_SCAN_PARAMS = Map.of(DIAGNOSTIC_SOURCE_SNYK_CODE, SCAN_PARAMS_CODE,
2429
DIAGNOSTIC_SOURCE_SNYK_IAC, SCAN_PARAMS_IAC, DIAGNOSTIC_SOURCE_SNYK_OSS, SCAN_PARAMS_OSS);
2530

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import java.io.ByteArrayOutputStream;
44
import java.io.InputStream;
55
import java.net.URL;
6+
import java.nio.file.Path;
67
import java.util.Base64;
78

9+
import org.eclipse.core.resources.IResource;
810
import org.eclipse.core.runtime.FileLocator;
9-
import org.eclipse.core.runtime.Path;
1011
import org.osgi.framework.Bundle;
1112

1213
public class ResourceUtils {
@@ -15,7 +16,7 @@ public ResourceUtils() {
1516
}
1617

1718
public static String getBase64Image(Bundle bundle, String icon) {
18-
URL imageUrl = FileLocator.find(bundle, new Path("icons/" + icon), null);
19+
URL imageUrl = FileLocator.find(bundle, new org.eclipse.core.runtime.Path("icons/" + icon), null);
1920

2021
byte[] imageData = getImageDataFromUrl(imageUrl);
2122

@@ -42,4 +43,7 @@ private static byte[] getImageDataFromUrl(URL imageUrl) {
4243
}
4344
}
4445

46+
public static Path getFullPath(IResource resource) {
47+
return resource.getLocation().toPath().toAbsolutePath();
48+
}
4549
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ public class SnykIcons {
2121
public static final ImageDescriptor SEVERITY_LOW = Activator.getImageDescriptor("/icons/severity-low.png");
2222

2323
public static final ImageDescriptor ENABLED = Activator.getImageDescriptor("/icons/enabled.png");
24+
public static final ImageDescriptor DISABLED = Activator.getImageDescriptor("/icons/transparent.png");
2425
}

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,12 @@ public void reset() {
6666
this.value = null;
6767
this.imageDescriptor = null;
6868
}
69-
69+
70+
/**
71+
* Provides the details to be displayed in the details view
72+
* @return html details
73+
*/
74+
public String getDetails() {
75+
return "";
76+
}
7077
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package io.snyk.eclipse.plugin.views.snyktoolview;
2+
3+
import static io.snyk.eclipse.plugin.domain.ProductConstants.DISPLAYED_CODE_QUALITY;
4+
import static io.snyk.eclipse.plugin.domain.ProductConstants.DISPLAYED_CODE_SECURITY;
5+
import static io.snyk.eclipse.plugin.domain.ProductConstants.DISPLAYED_IAC;
6+
import static io.snyk.eclipse.plugin.domain.ProductConstants.DISPLAYED_OSS;
7+
8+
import java.nio.file.Path;
9+
10+
import org.eclipse.core.resources.ResourcesPlugin;
11+
import org.eclipse.jface.resource.ImageDescriptor;
12+
import org.eclipse.swt.graphics.Image;
13+
import org.eclipse.ui.model.WorkbenchLabelProvider;
14+
15+
import io.snyk.eclipse.plugin.domain.ProductConstants;
16+
17+
public class ContentRootNode extends BaseTreeNode {
18+
private Path path;
19+
private String name;
20+
21+
public ContentRootNode(String name, Path value) {
22+
super(value);
23+
reset();
24+
this.name = name;
25+
this.setPath(value);
26+
}
27+
28+
@Override
29+
public ImageDescriptor getImageDescriptor() {
30+
WorkbenchLabelProvider labelProvider = new WorkbenchLabelProvider();
31+
try {
32+
var object = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
33+
Image image = labelProvider.getImage(object);
34+
if (image == null)
35+
return null;
36+
37+
return ImageDescriptor.createFromImage(image);
38+
} finally {
39+
labelProvider.dispose();
40+
}
41+
}
42+
43+
public ProductTreeNode getProductNode(String product) {
44+
if (product == null) {
45+
return null;
46+
}
47+
switch (product) {
48+
case ProductConstants.DISPLAYED_OSS:
49+
return (ProductTreeNode) this.getChildren()[0];
50+
case ProductConstants.DISPLAYED_CODE_SECURITY:
51+
return (ProductTreeNode) this.getChildren()[1];
52+
case ProductConstants.DISPLAYED_CODE_QUALITY:
53+
return (ProductTreeNode) this.getChildren()[2];
54+
case ProductConstants.DISPLAYED_IAC:
55+
return (ProductTreeNode) this.getChildren()[3];
56+
}
57+
return null;
58+
}
59+
60+
@Override
61+
public void reset() {
62+
var ossRootNode = new ProductTreeNode(DISPLAYED_OSS);
63+
ossRootNode.setParent(this);
64+
65+
var codeSecurityRootNode = new ProductTreeNode(DISPLAYED_CODE_SECURITY);
66+
codeSecurityRootNode.setParent(this);
67+
68+
var codeQualityRootNode = new ProductTreeNode(DISPLAYED_CODE_QUALITY);
69+
codeQualityRootNode.setParent(this);
70+
71+
var iacRootNode = new ProductTreeNode(DISPLAYED_IAC);
72+
iacRootNode.setParent(this);
73+
74+
ProductTreeNode[] productNodes = new ProductTreeNode[] { ossRootNode, codeSecurityRootNode, codeQualityRootNode, iacRootNode, };
75+
this.setChildren(productNodes);
76+
}
77+
78+
@Override
79+
public String getText() {
80+
return name;
81+
}
82+
83+
public Path getPath() {
84+
return path;
85+
}
86+
87+
public void setPath(Path path) {
88+
this.path = path;
89+
}
90+
}

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

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

3+
import io.snyk.languageserver.protocolextension.FileTreeNode;
4+
35
import org.eclipse.jface.resource.ImageDescriptor;
46
import org.eclipse.jface.viewers.TreeViewer;
57

8+
69
/**
710
* This interface captures the externally used methods with the tool window.
811
* Having it, should allow for easier testing of the business logic apart from
@@ -16,7 +19,7 @@ public interface ISnykToolView {
1619

1720
String NODE_TEXT_SCANNING = "Scanning...";
1821
String NODE_TEXT_NO_ISSUES_FOUND = "No issues found";
19-
String NODE_TEXT_EROR = "An error occurred";
22+
String NODE_TEXT_ERROR = "An error occurred";
2023

2124
/**
2225
* Updates the text of the given node
@@ -26,50 +29,51 @@ public interface ISnykToolView {
2629
*/
2730
abstract void setNodeText(BaseTreeNode node, String text);
2831

29-
/**
30-
* Sets the icon of the given node
31-
*
32-
* @param icon
33-
*/
34-
abstract void setNodeIcon(ImageDescriptor icon);
35-
3632
/**
3733
* Adds an issue node to the parent (usually a file node)
3834
*
3935
* @param parent
4036
* @param toBeAdded
4137
*/
42-
abstract void addIssueNode(BaseTreeNode parent, BaseTreeNode toBeAdded);
38+
abstract void addIssueNode(FileTreeNode parent, IssueTreeNode toBeAdded);
4339

4440
/**
4541
* Adds a file node (usually below the product node)
4642
*
4743
* @param parent
4844
* @param toBeAdded
4945
*/
50-
abstract void addFileNode(BaseTreeNode parent, BaseTreeNode toBeAdded);
46+
abstract void addFileNode(ProductTreeNode parent, FileTreeNode toBeAdded);
5147

5248
/**
5349
* Adds an info node (usually below the product node)
5450
*
5551
* @param parent
5652
* @param toBeAdded
5753
*/
58-
abstract void addInfoNode(BaseTreeNode parent, BaseTreeNode toBeAdded);
54+
abstract void addInfoNode(ProductTreeNode parent, InfoTreeNode toBeAdded);
5955

6056
/**
6157
* Returns the product node
6258
*
63-
* @param product the product. ProductConstants#DISPLAY_*
59+
* @param product the product. ProductConstants#DISPLAY_
60+
* @param folderPath TODO*
6461
* @return
6562
*/
66-
abstract BaseTreeNode getProductNode(String product);
63+
abstract ProductTreeNode getProductNode(String product, String folderPath);
6764

6865
/**
6966
* Resets a product node
7067
*/
7168
abstract void resetNode(BaseTreeNode node);
7269

70+
/**
71+
* Remove all info nodes from the product tree node
72+
*
73+
* @param node
74+
*/
75+
abstract void removeInfoNodes(ProductTreeNode node);
76+
7377
/**
7478
* Refreshes the tree display
7579
*/
@@ -94,5 +98,4 @@ static String getPlural(long count) {
9498
}
9599

96100
abstract TreeViewer getTreeViewer();
97-
98101
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.snyk.eclipse.plugin.views.snyktoolview;
2+
3+
public class InfoTreeNode extends BaseTreeNode {
4+
5+
public InfoTreeNode(Object value) {
6+
super(value);
7+
}
8+
9+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package io.snyk.eclipse.plugin.views.snyktoolview;
2+
3+
import org.eclipse.core.resources.ResourcesPlugin;
4+
import org.eclipse.jface.resource.ImageDescriptor;
5+
import org.eclipse.swt.graphics.Image;
6+
import org.eclipse.ui.model.WorkbenchLabelProvider;
7+
8+
import io.snyk.eclipse.plugin.domain.ProductConstants;
9+
import io.snyk.eclipse.plugin.utils.SnykIcons;
10+
import io.snyk.languageserver.protocolextension.messageObjects.scanResults.Issue;
11+
12+
public class IssueTreeNode extends BaseTreeNode {
13+
private Issue issue;
14+
15+
public IssueTreeNode(Issue issue) {
16+
super(issue);
17+
this.setIssue(issue);
18+
}
19+
20+
@Override
21+
public String getText() {
22+
return getIssue().getDisplayTitle();
23+
}
24+
25+
@Override
26+
public String getDetails() {
27+
return getIssue().additionalData().customUIContent();
28+
}
29+
30+
@Override
31+
public ImageDescriptor getImageDescriptor() {
32+
switch(getIssue().severity()) {
33+
case ProductConstants.SEVERITY_CRITICAL:
34+
return SnykIcons.SEVERITY_CRITICAL;
35+
case ProductConstants.SEVERITY_HIGH:
36+
return SnykIcons.SEVERITY_HIGH;
37+
case ProductConstants.SEVERITY_MEDIUM:
38+
return SnykIcons.SEVERITY_MEDIUM;
39+
case ProductConstants.SEVERITY_LOW:
40+
return SnykIcons.SEVERITY_LOW;
41+
default:
42+
return super.getImageDescriptor();
43+
}
44+
}
45+
46+
public Issue getIssue() {
47+
return issue;
48+
}
49+
50+
public void setIssue(Issue issue) {
51+
this.issue = issue;
52+
}
53+
54+
55+
}

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

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

3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.HashSet;
6+
7+
import org.eclipse.jface.resource.ImageDescriptor;
8+
import org.eclipse.jface.viewers.TreeNode;
9+
10+
import io.snyk.eclipse.plugin.Activator;
311
import io.snyk.eclipse.plugin.domain.ProductConstants;
412
import io.snyk.eclipse.plugin.utils.SnykIcons;
513

614
public class ProductTreeNode extends BaseTreeNode {
715

816
private String product;
917

10-
public ProductTreeNode(Object value) {
18+
public ProductTreeNode(String value) {
1119
super(value);
12-
this.setProduct(value.toString());
20+
this.setProduct(value);
1321

14-
switch (value.toString()) {
22+
switch (value) {
1523
case ProductConstants.DISPLAYED_OSS:
1624
setImageDescriptor(SnykIcons.OSS);
1725
break;
@@ -32,6 +40,24 @@ public void setText(String text) {
3240
this.setValue(text);
3341
}
3442

43+
public void removeInfoNodes() {
44+
var childs = getChildren();
45+
if (childs == null || childs.length == 0) {
46+
return;
47+
}
48+
49+
var list = new ArrayList<TreeNode>(Arrays.asList(getChildren()));
50+
51+
var newList = new HashSet<BaseTreeNode>();
52+
for (TreeNode node : list) {
53+
if (!(node instanceof InfoTreeNode) && node instanceof BaseTreeNode) {
54+
newList.add((BaseTreeNode) node);
55+
}
56+
}
57+
58+
setChildren(newList.toArray(new BaseTreeNode[0]));
59+
}
60+
3561
@Override
3662
public void setValue(Object value) {
3763
if (!(value instanceof String))

0 commit comments

Comments
 (0)