Skip to content

Commit e5565db

Browse files
authored
feat: Show non Java Projects in the Java Projects explorer (#744)
* feat: Show non Java Projects in the Java Projects explorer --------- Signed-off-by: Sheng Chen <[email protected]>
1 parent 169e166 commit e5565db

File tree

6 files changed

+73
-38
lines changed

6 files changed

+73
-38
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77
## 0.22.0
88
### Added
99
- Display non-Java files in Java Projects explorer. [#145](https://github.com/microsoft/vscode-java-dependency/issues/145)
10+
- Show non Java Projects in the Java Projects explorer. [#736](https://github.com/microsoft/vscode-java-dependency/issues/736)
11+
- Support creating files and folders in Java Projects explorer. [#598](https://github.com/microsoft/vscode-java-dependency/issues/598)
1012
- Apply file decorators to project level. [#481](https://github.com/microsoft/vscode-java-dependency/issues/481)
1113
- Give more hints about the project import status. [#580](https://github.com/microsoft/vscode-java-dependency/issues/580)
12-
- Support creating files and folders in Java Projects explorer. [#598](https://github.com/microsoft/vscode-java-dependency/issues/598)
13-
1414
### Fixed
1515
- Apply `files.exclude` to Java Projects explorer. [#214](https://github.com/microsoft/vscode-java-dependency/issues/214)
1616

extension.bundle.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ export { languageServerApiManager } from "./src/languageServerApi/languageServer
2828

2929
// tasks
3030
export { BuildTaskProvider, categorizePaths, getFinalPaths } from "./src/tasks/build/buildTaskProvider";
31+
32+
// delegate commands
33+
export { Jdtls } from "./src/java/jdtls";

jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.LinkedList;
2020
import java.util.List;
2121
import java.util.Map;
22+
import java.util.Set;
2223
import java.util.function.BiFunction;
2324
import java.util.stream.Collectors;
2425

@@ -31,6 +32,7 @@
3132
import org.eclipse.core.resources.IWorkspaceRoot;
3233
import org.eclipse.core.resources.ResourcesPlugin;
3334
import org.eclipse.core.runtime.CoreException;
35+
import org.eclipse.core.runtime.IPath;
3436
import org.eclipse.core.runtime.IProgressMonitor;
3537
import org.eclipse.core.runtime.IStatus;
3638
import org.eclipse.core.runtime.OperationCanceledException;
@@ -257,18 +259,22 @@ private static List<PackageNode> getParentAncestorNodes(IResource element) throw
257259
* Get the class path container list.
258260
*/
259261
private static List<PackageNode> getProjectChildren(PackageParams query, IProgressMonitor pm) {
260-
IJavaProject javaProject = getJavaProject(query.getProjectUri());
261-
if (javaProject != null) {
262-
refreshLocal(javaProject.getProject(), pm);
263-
List<Object> children = new LinkedList<>();
264-
boolean hasReferencedLibraries = false;
265-
try {
262+
IProject project = getProject(query.getProjectUri());
263+
if (project == null) {
264+
JdtlsExtActivator.logError("Failed to find project at: " + query.getProjectUri());
265+
}
266+
267+
List<Object> children = new LinkedList<>();
268+
boolean hasReferencedLibraries = false;
269+
IJavaProject javaProject = JavaCore.create(project);
270+
try {
271+
if (ProjectUtils.isJavaProject(project) && javaProject != null) {
272+
refreshLocal(javaProject.getProject(), pm);
266273
IClasspathEntry[] references = javaProject.getRawClasspath();
267274
for (IClasspathEntry entry : references) {
268275
int entryKind = entry.getEntryKind();
269276
if (entryKind == IClasspathEntry.CPE_SOURCE) {
270-
IPackageFragmentRoot[] packageFragmentRoots = javaProject.findPackageFragmentRoots(entry);
271-
children.addAll(Arrays.asList(packageFragmentRoots));
277+
Collections.addAll(children, javaProject.findPackageFragmentRoots(entry));
272278
} else if (entryKind == IClasspathEntry.CPE_CONTAINER) {
273279
children.add(entry);
274280
} else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
@@ -278,24 +284,32 @@ private static List<PackageNode> getProjectChildren(PackageParams query, IProgre
278284
}
279285
}
280286
Collections.addAll(children, javaProject.getNonJavaResources());
281-
} catch (CoreException e) {
282-
JdtlsExtActivator.logException("Problem load project library ", e);
287+
} else {
288+
Set<IPath> projectPaths = Arrays.stream(ProjectUtils.getAllProjects())
289+
.map(IProject::getLocation).collect(Collectors.toSet());
290+
IResource[] members = project.members();
291+
for (IResource member : members) {
292+
if (!projectPaths.contains(member.getLocation())) {
293+
children.add(member);
294+
}
295+
}
283296
}
297+
} catch (CoreException e) {
298+
JdtlsExtActivator.logException("Problem load project library ", e);
299+
}
284300

285-
ResourceSet resourceSet = new ResourceSet(children);
286-
ResourceVisitor visitor = new JavaResourceVisitor(javaProject);
287-
resourceSet.accept(visitor);
288-
List<PackageNode> result = visitor.getNodes();
301+
ResourceSet resourceSet = new ResourceSet(children);
302+
ResourceVisitor visitor = new JavaResourceVisitor(javaProject);
303+
resourceSet.accept(visitor);
304+
List<PackageNode> result = visitor.getNodes();
289305

290-
// Invisible project will always have the referenced libraries entry
291-
if (!ProjectUtils.isVisibleProject(javaProject.getProject())) {
292-
result.add(PackageNode.REFERENCED_LIBRARIES_CONTAINER);
293-
} else if (hasReferencedLibraries) {
294-
result.add(PackageNode.IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER);
295-
}
296-
return result;
306+
// Invisible project will always have the referenced libraries entry
307+
if (!ProjectUtils.isVisibleProject(project)) {
308+
result.add(PackageNode.REFERENCED_LIBRARIES_CONTAINER);
309+
} else if (hasReferencedLibraries) {
310+
result.add(PackageNode.IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER);
297311
}
298-
return Collections.emptyList();
312+
return result;
299313
}
300314

301315
private static List<PackageNode> getContainerChildren(PackageParams query, IProgressMonitor pm) {
@@ -567,7 +581,7 @@ private static Object[] findJarDirectoryChildren(JarEntryDirectory directory, St
567581
return null;
568582
}
569583

570-
public static IJavaProject getJavaProject(String projectUri) {
584+
public static IProject getProject(String projectUri) {
571585
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
572586
IContainer[] containers = root.findContainersForLocationURI(JDTUtils.toURI(projectUri));
573587

@@ -576,8 +590,7 @@ public static IJavaProject getJavaProject(String projectUri) {
576590
}
577591

578592
// For multi-module scenario, findContainersForLocationURI API may return a container array,
579-
// need filter out non-Java project and put the result from the nearest project in front.
580-
containers = Arrays.stream(containers).filter(c -> ProjectUtils.isJavaProject(c.getProject())).toArray(IContainer[]::new);
593+
// put the result from the nearest project in front.
581594
Arrays.sort(containers, (Comparator<IContainer>) (IContainer a, IContainer b) -> {
582595
return a.getFullPath().toPortableString().length() - b.getFullPath().toPortableString().length();
583596
});
@@ -587,11 +600,16 @@ public static IJavaProject getJavaProject(String projectUri) {
587600
if (!project.exists()) {
588601
return null;
589602
}
590-
return JavaCore.create(project);
603+
return project;
591604
}
592605
return null;
593606
}
594607

608+
public static IJavaProject getJavaProject(String projectUri) {
609+
IProject project = getProject(projectUri);
610+
return JavaCore.create(project);
611+
}
612+
595613
private static void refreshLocal(IResource resource, IProgressMonitor monitor) {
596614
if (resource == null || !resource.exists()) {
597615
return;

jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/ProjectCommand.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.io.FileOutputStream;
1919
import java.io.IOException;
2020
import java.util.ArrayList;
21+
import java.util.Arrays;
2122
import java.util.HashSet;
2223
import java.util.List;
2324
import java.util.Objects;
@@ -98,10 +99,20 @@ public static List<PackageNode> listProjects(List<Object> arguments, IProgressMo
9899
String workspaceUri = (String) arguments.get(0);
99100
IPath workspaceFolderPath = ResourceUtils.canonicalFilePathFromURI(workspaceUri);
100101

101-
IJavaProject[] javaProjects = ProjectUtils.getJavaProjects();
102+
IProject[] projects;
103+
boolean includeNonJava = false;
104+
if (arguments.size() > 1) {
105+
includeNonJava = (boolean) arguments.get(1);
106+
}
107+
if (includeNonJava) {
108+
projects = ProjectUtils.getAllProjects();
109+
} else {
110+
projects = Arrays.stream(ProjectUtils.getJavaProjects())
111+
.map(IJavaProject::getProject).toArray(IProject[]::new);
112+
}
113+
102114
ArrayList<PackageNode> children = new ArrayList<>();
103-
for (IJavaProject javaProject : javaProjects) {
104-
IProject project = javaProject.getProject();
115+
for (IProject project : projects) {
105116
if (!project.isAccessible() || project.getLocation() == null) {
106117
continue;
107118
}

src/java/jdtls.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import { INodeData } from "./nodeData";
1111

1212
export namespace Jdtls {
1313
export async function getProjects(params: string): Promise<INodeData[]> {
14-
return await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_PROJECT_LIST, params) || [];
14+
return await commands.executeCommand(
15+
Commands.EXECUTE_WORKSPACE_COMMAND,
16+
Commands.JAVA_PROJECT_LIST,
17+
params,
18+
true /*includeNonJavaProjects*/
19+
) || [];
1520
}
1621

1722
export async function getProjectUris(): Promise<string[]> {

test/maven-suite/projectView.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import * as assert from "assert";
55
import * as clipboardy from "clipboardy";
66
import * as path from "path";
77
import * as vscode from "vscode";
8-
import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode, IMainClassInfo,
9-
INodeData, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle";
8+
import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode,
9+
INodeData, Jdtls, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle";
1010
import { fsPath, setupTestEnv, Uris } from "../shared";
1111
import { sleep } from "../util";
1212

@@ -175,8 +175,7 @@ suite("Maven Project View Tests", () => {
175175
test("Can execute command java.project.list correctly", async function() {
176176
const workspaceFolders = vscode.workspace.workspaceFolders;
177177
assert.ok(workspaceFolders, `There should be valid workspace folders`);
178-
const projects = await vscode.commands.executeCommand<INodeData[]>(Commands.EXECUTE_WORKSPACE_COMMAND,
179-
Commands.JAVA_PROJECT_LIST, workspaceFolders![0].uri.toString());
178+
const projects = await Jdtls.getProjects(workspaceFolders![0].uri.toString());
180179
assert.equal(projects?.length, 1, "project's length should be 1");
181180
assert.equal(projects![0].name, "my-app", "project should be my-app");
182181
});
@@ -217,8 +216,7 @@ suite("Maven Project View Tests", () => {
217216
test("Can execute command java.project.getMainClasses correctly", async function() {
218217
const workspaceFolders = vscode.workspace.workspaceFolders;
219218
assert.ok(workspaceFolders, `There should be valid workspace folders`);
220-
const mainClasses = await vscode.commands.executeCommand<IMainClassInfo[]>(Commands.EXECUTE_WORKSPACE_COMMAND,
221-
Commands.JAVA_PROJECT_GETMAINCLASSES, workspaceFolders![0].uri.toString());
219+
const mainClasses = await Jdtls.getMainClasses(workspaceFolders![0].uri.toString());
222220
assert.equal(mainClasses?.length, 1, "mainClasses' length should be 1");
223221
assert.equal(mainClasses![0].name, "com.mycompany.app.App", "mainClasses[0]'s name should be com.mycompany.app.App");
224222
});

0 commit comments

Comments
 (0)