Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## 0.22.0
### Added
- Display non-Java files in Java Projects explorer. [#145](https://github.com/microsoft/vscode-java-dependency/issues/145)
- Show non Java Projects in the Java Projects explorer. [#736](https://github.com/microsoft/vscode-java-dependency/issues/736)
- Support creating files and folders in Java Projects explorer. [#598](https://github.com/microsoft/vscode-java-dependency/issues/598)
- Apply file decorators to project level. [#481](https://github.com/microsoft/vscode-java-dependency/issues/481)
- Give more hints about the project import status. [#580](https://github.com/microsoft/vscode-java-dependency/issues/580)
- Support creating files and folders in Java Projects explorer. [#598](https://github.com/microsoft/vscode-java-dependency/issues/598)

### Fixed
- Apply `files.exclude` to Java Projects explorer. [#214](https://github.com/microsoft/vscode-java-dependency/issues/214)

Expand Down
3 changes: 3 additions & 0 deletions extension.bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ export { languageServerApiManager } from "./src/languageServerApi/languageServer

// tasks
export { BuildTaskProvider, categorizePaths, getFinalPaths } from "./src/tasks/build/buildTaskProvider";

// delegate commands
export { Jdtls } from "./src/java/jdtls";
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

Expand All @@ -31,6 +32,7 @@
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
Expand Down Expand Up @@ -257,18 +259,22 @@ private static List<PackageNode> getParentAncestorNodes(IResource element) throw
* Get the class path container list.
*/
private static List<PackageNode> getProjectChildren(PackageParams query, IProgressMonitor pm) {
IJavaProject javaProject = getJavaProject(query.getProjectUri());
if (javaProject != null) {
refreshLocal(javaProject.getProject(), pm);
List<Object> children = new LinkedList<>();
boolean hasReferencedLibraries = false;
try {
IProject project = getProject(query.getProjectUri());
if (project == null) {
JdtlsExtActivator.logError("Failed to find project at: " + query.getProjectUri());
}

List<Object> children = new LinkedList<>();
boolean hasReferencedLibraries = false;
IJavaProject javaProject = JavaCore.create(project);
try {
if (ProjectUtils.isJavaProject(project) && javaProject != null) {
refreshLocal(javaProject.getProject(), pm);
IClasspathEntry[] references = javaProject.getRawClasspath();
for (IClasspathEntry entry : references) {
int entryKind = entry.getEntryKind();
if (entryKind == IClasspathEntry.CPE_SOURCE) {
IPackageFragmentRoot[] packageFragmentRoots = javaProject.findPackageFragmentRoots(entry);
children.addAll(Arrays.asList(packageFragmentRoots));
Collections.addAll(children, javaProject.findPackageFragmentRoots(entry));
} else if (entryKind == IClasspathEntry.CPE_CONTAINER) {
children.add(entry);
} else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
Expand All @@ -278,24 +284,32 @@ private static List<PackageNode> getProjectChildren(PackageParams query, IProgre
}
}
Collections.addAll(children, javaProject.getNonJavaResources());
} catch (CoreException e) {
JdtlsExtActivator.logException("Problem load project library ", e);
} else {
Set<IPath> projectPaths = Arrays.stream(ProjectUtils.getAllProjects())
.map(IProject::getLocation).collect(Collectors.toSet());
IResource[] members = project.members();
for (IResource member : members) {
if (!projectPaths.contains(member.getLocation())) {
children.add(member);
}
}
}
} catch (CoreException e) {
JdtlsExtActivator.logException("Problem load project library ", e);
}

ResourceSet resourceSet = new ResourceSet(children);
ResourceVisitor visitor = new JavaResourceVisitor(javaProject);
resourceSet.accept(visitor);
List<PackageNode> result = visitor.getNodes();
ResourceSet resourceSet = new ResourceSet(children);
ResourceVisitor visitor = new JavaResourceVisitor(javaProject);
resourceSet.accept(visitor);
List<PackageNode> result = visitor.getNodes();

// Invisible project will always have the referenced libraries entry
if (!ProjectUtils.isVisibleProject(javaProject.getProject())) {
result.add(PackageNode.REFERENCED_LIBRARIES_CONTAINER);
} else if (hasReferencedLibraries) {
result.add(PackageNode.IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER);
}
return result;
// Invisible project will always have the referenced libraries entry
if (!ProjectUtils.isVisibleProject(project)) {
result.add(PackageNode.REFERENCED_LIBRARIES_CONTAINER);
} else if (hasReferencedLibraries) {
result.add(PackageNode.IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER);
}
return Collections.emptyList();
return result;
}

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

public static IJavaProject getJavaProject(String projectUri) {
public static IProject getProject(String projectUri) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IContainer[] containers = root.findContainersForLocationURI(JDTUtils.toURI(projectUri));

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

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

public static IJavaProject getJavaProject(String projectUri) {
IProject project = getProject(projectUri);
return JavaCore.create(project);
}

private static void refreshLocal(IResource resource, IProgressMonitor monitor) {
if (resource == null || !resource.exists()) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -98,10 +99,20 @@ public static List<PackageNode> listProjects(List<Object> arguments, IProgressMo
String workspaceUri = (String) arguments.get(0);
IPath workspaceFolderPath = ResourceUtils.canonicalFilePathFromURI(workspaceUri);

IJavaProject[] javaProjects = ProjectUtils.getJavaProjects();
IProject[] projects;
boolean includeNonJava = false;
if (arguments.size() > 1) {
includeNonJava = (boolean) arguments.get(1);
}
if (includeNonJava) {
projects = ProjectUtils.getAllProjects();
} else {
projects = Arrays.stream(ProjectUtils.getJavaProjects())
.map(IJavaProject::getProject).toArray(IProject[]::new);
}

ArrayList<PackageNode> children = new ArrayList<>();
for (IJavaProject javaProject : javaProjects) {
IProject project = javaProject.getProject();
for (IProject project : projects) {
if (!project.isAccessible() || project.getLocation() == null) {
continue;
}
Expand Down
7 changes: 6 additions & 1 deletion src/java/jdtls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import { INodeData } from "./nodeData";

export namespace Jdtls {
export async function getProjects(params: string): Promise<INodeData[]> {
return await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_PROJECT_LIST, params) || [];
return await commands.executeCommand(
Commands.EXECUTE_WORKSPACE_COMMAND,
Commands.JAVA_PROJECT_LIST,
params,
true /*includeNonJavaProjects*/
) || [];
}

export async function getProjectUris(): Promise<string[]> {
Expand Down
10 changes: 4 additions & 6 deletions test/maven-suite/projectView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import * as assert from "assert";
import * as clipboardy from "clipboardy";
import * as path from "path";
import * as vscode from "vscode";
import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode, IMainClassInfo,
INodeData, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle";
import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode,
INodeData, Jdtls, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle";
import { fsPath, setupTestEnv, Uris } from "../shared";
import { sleep } from "../util";

Expand Down Expand Up @@ -175,8 +175,7 @@ suite("Maven Project View Tests", () => {
test("Can execute command java.project.list correctly", async function() {
const workspaceFolders = vscode.workspace.workspaceFolders;
assert.ok(workspaceFolders, `There should be valid workspace folders`);
const projects = await vscode.commands.executeCommand<INodeData[]>(Commands.EXECUTE_WORKSPACE_COMMAND,
Commands.JAVA_PROJECT_LIST, workspaceFolders![0].uri.toString());
const projects = await Jdtls.getProjects(workspaceFolders![0].uri.toString());
assert.equal(projects?.length, 1, "project's length should be 1");
assert.equal(projects![0].name, "my-app", "project should be my-app");
});
Expand Down Expand Up @@ -217,8 +216,7 @@ suite("Maven Project View Tests", () => {
test("Can execute command java.project.getMainClasses correctly", async function() {
const workspaceFolders = vscode.workspace.workspaceFolders;
assert.ok(workspaceFolders, `There should be valid workspace folders`);
const mainClasses = await vscode.commands.executeCommand<IMainClassInfo[]>(Commands.EXECUTE_WORKSPACE_COMMAND,
Commands.JAVA_PROJECT_GETMAINCLASSES, workspaceFolders![0].uri.toString());
const mainClasses = await Jdtls.getMainClasses(workspaceFolders![0].uri.toString());
assert.equal(mainClasses?.length, 1, "mainClasses' length should be 1");
assert.equal(mainClasses![0].name, "com.mycompany.app.App", "mainClasses[0]'s name should be com.mycompany.app.App");
});
Expand Down