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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ You can turn these reminders on or off at any time with the `java.dependency.ena
| `java.dependency.packagePresentation` | Specify how to display the package. Supported values are: `flat`, `hierarchical`.| `flat` |
| `java.dependency.enableDependencyCheckup` | Show reminders when your Java runtimes or dependencies need an upgrade. | `true` |
| `java.project.exportJar.targetPath` | The output path of export jar. When this setting is **empty** , a file explorer will pop up to let the user select the output location.| `${workspaceFolder}/${workspaceFolderBasename}.jar` |
| `java.project.explorer.showNonJavaResources` | When enabled, the explorer shows non-Java resources. | `true` |
| `java.project.explorer.showNonJavaResources` | When enabled, the explorer shows non-Java resources. When disabled, workspace folders without Java projects are hidden. | `true` |

## Contribution

Expand Down
2 changes: 1 addition & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"configuration.java.dependency.refreshDelay": "The delay time (ms) the auto refresh is invoked when changes are detected",
"configuration.java.dependency.packagePresentation": "Package presentation mode: flat or hierarchical",
"configuration.java.dependency.enableDependencyCheckup": "Show reminders when your Java runtimes or dependencies need an upgrade.",
"configuration.java.project.explorer.showNonJavaResources": "When enabled, the explorer shows non-Java resources.",
"configuration.java.project.explorer.showNonJavaResources": "When enabled, the explorer shows non-Java resources. When disabled, workspace folders without Java projects are hidden.",
"configuration.java.project.exportJar.targetPath.customization": "The output path of the exported jar. Leave it empty if you want to manually pick the output location.",
"configuration.java.project.exportJar.targetPath.workspaceFolder": "Export the jar file into the workspace folder. Its name is the same as the folder's.",
"configuration.java.project.exportJar.targetPath.select": "Select output location manually when exporting the jar file.",
Expand Down
2 changes: 1 addition & 1 deletion package.nls.zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"configuration.java.dependency.autoRefresh": "在 Java 项目管理器中自动同步修改",
"configuration.java.dependency.refreshDelay": "控制 Java 项目管理器刷新的延迟时间 (毫秒)",
"configuration.java.dependency.packagePresentation": "Java 包显示方式: 平行显示或者分层显示",
"configuration.java.project.explorer.showNonJavaResources": "启用时 Java 项目管理器将显示非 Java 资源。",
"configuration.java.project.explorer.showNonJavaResources": "启用时,Java 项目管理器将显示非 Java 资源;禁用时,将隐藏不包含 Java 项目的工作区文件夹。",
"configuration.java.project.exportJar.targetPath.customization": "导出 Jar 文件的路径。您可以将此选项置为空串来手动选择 jar 文件的导出路径。",
"configuration.java.project.exportJar.targetPath.workspaceFolder": "导出 Jar 文件到工作空间文件夹下。Jar 文件的名称和工作空间文件夹的名称相同。",
"configuration.java.project.exportJar.targetPath.select": "在导出 Jar 文件时手动选择输出目录。",
Expand Down
1 change: 1 addition & 0 deletions package.nls.zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"configuration.java.dependency.autoRefresh": "在 Java 專案管理員中自動同步修改",
"configuration.java.dependency.refreshDelay": "控制 Java 專案管理員重新整理的延遲時間 (毫秒)",
"configuration.java.dependency.packagePresentation": "Java 套件顯示方式: 平行顯示或者分層顯示",
"configuration.java.project.explorer.showNonJavaResources": "啟用時,Java 專案管理員會顯示非 Java 資源;停用時,將隱藏不包含 Java 專案的工作區資料夾。",
"configuration.java.project.exportJar.targetPath.customization": "匯出 Jar 檔案的路徑。如果您想要手動選擇輸出路徑,可以不填。",
"configuration.java.project.exportJar.targetPath.workspaceFolder": "匯出 Jar 檔案到工作區資料夾下。Jar 檔案的名稱和工作區資料夾的名稱相同。",
"configuration.java.project.exportJar.targetPath.select": "在匯出 Jar 檔案時手動選擇輸出位置。",
Expand Down
19 changes: 14 additions & 5 deletions src/views/dependencyDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,20 @@ export class DependencyDataProvider implements TreeDataProvider<ExplorerNode> {
const folders = workspace.workspaceFolders;
if (folders && folders.length) {
if (folders.length > 1) {
folders.forEach((folder) => rootItems.push(new WorkspaceNode({
name: folder.name,
uri: folder.uri.toString(),
kind: NodeKind.Workspace,
}, undefined)));
const javaProjectsByFolder = Settings.nonJavaResourcesFiltered()
? await Promise.all(folders.map((folder) => Jdtls.getProjects(folder.uri.toString())))
: undefined;
folders.forEach((folder, index) => {
// Java-only mode should not leave empty non-Java workspace roots in the tree.
if (javaProjectsByFolder && javaProjectsByFolder[index].length === 0) {
return;
}
rootItems.push(new WorkspaceNode({
name: folder.name,
uri: folder.uri.toString(),
kind: NodeKind.Workspace,
}, undefined));
});
this._rootItems = rootItems;
} else {
const result: INodeData[] = await Jdtls.getProjects(folders[0].uri.toString());
Expand Down
94 changes: 90 additions & 4 deletions test/e2e-plans/java-dep-project-explorer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
# - linkWithFolderExplorer reveals active file in tree
# - unlinkWithFolderExplorer stops auto-reveal
# - revealInProjectExplorer reveals file from File Explorer context menu
# - hideNonJavaResources removes non-Java workspace roots while preserving
# Java roots across refreshes and newly imported projects
#
# Usage:
# npx autotest run test/e2e-plans/java-dep-project-explorer.yaml --vsix <path-to-vsix>

name: "Java Dependency — Project Explorer"
description: |
Tests the Java Projects explorer view: focus, link/unlink with editor,
reveal in project explorer.
reveal in project explorer, and filtering non-Java workspace roots without
hiding Java roots during refresh or project import.

setup:
extension: "redhat.java"
Expand Down Expand Up @@ -153,7 +156,7 @@ steps:
exact: true
timeout: 15

# ── Test 5: mixed multi-root project attribution (#1060) ──
# ── Test 5: mixed multi-root filtering and project attribution (#758, #1060) ──
# First establish a mixed workspace and refresh it into WorkspaceNode roots.
# The smoke-test driver renders folder pickers as an internal quick input:
# entering an absolute folder path opens it, then the Add button confirms it.
Expand Down Expand Up @@ -186,10 +189,68 @@ steps:
action: "wait 1 seconds"
verifyTreeItem:
name: "non-java"
exact: true
count: 1
level: 1
inView: "Java Projects"
timeout: 15

# Hide Non-Java Resources now applies to the workspace-root level as well:
# roots without any Java project disappear, while Java workspace roots remain.
- id: "hide-non-java-workspace-root"
action: 'clickViewTitleAction "Java Projects" "Hide Non-Java Resources"'

- id: "verify-non-java-workspace-root-hidden"
action: "wait 1 seconds"
verifyTreeItem:
name: "non-java"
exact: true
visible: false
level: 1
inView: "Java Projects"
timeout: 30

- id: "verify-java-workspace-root-remains"
action: "wait 1 seconds"
verifyTreeItem:
name: "maven"
exact: true
count: 1
level: 1
inView: "Java Projects"
timeout: 15

# Add a Java folder after the mixed multi-root structure already exists and
# refresh it into the expected WorkspaceNode -> ProjectNode hierarchy.
- id: "expand-java-workspace-root"
action: "expandTreeItem maven"

- id: "verify-nested-java-project-remains"
action: "wait 1 seconds"
verifyTreeItem:
name: "my-app"
exact: true
count: 1
level: 2
inView: "Java Projects"
timeout: 15

# Rebuilding the roots must preserve the Java-only view rather than
# reintroducing the filtered workspace folder.
- id: "refresh-hidden-workspace-roots"
action: "executeVSCodeCommand java.view.package.refresh"

- id: "verify-non-java-root-stays-hidden-after-refresh"
action: "wait 1 seconds"
verifyTreeItem:
name: "non-java"
exact: true
visible: false
level: 1
inView: "Java Projects"
timeout: 30

# Add a Java folder while non-Java roots are hidden. A newly imported Java
# workspace root must still appear, while the existing non-Java root remains
# filtered.
- id: "invoke-add-java-root"
action: "executeVSCodeCommand workbench.action.addRootFolder"

Expand All @@ -214,8 +275,19 @@ steps:
exact: true
count: 1
level: 1
inView: "Java Projects"
timeout: 15

- id: "verify-non-java-root-stays-hidden-after-java-import"
action: "wait 1 seconds"
verifyTreeItem:
name: "non-java"
exact: true
visible: false
level: 1
inView: "Java Projects"
timeout: 30

# Deterministically simulate the onDidProjectsImport path. Before #1060 this
# command appended a second top-level ProjectNode named "simple" beside the
# existing WorkspaceNode. The fixed provider ignores progressive insertion
Expand All @@ -227,4 +299,18 @@ steps:
exact: true
count: 1
level: 1
inView: "Java Projects"
timeout: 15

- id: "restore-non-java-workspace-root"
action: 'clickViewTitleAction "Java Projects" "Show Non-Java Resources"'

- id: "verify-non-java-workspace-root-restored"
action: "wait 1 seconds"
verifyTreeItem:
name: "non-java"
exact: true
count: 1
level: 1
inView: "Java Projects"
timeout: 30
39 changes: 38 additions & 1 deletion test/multiple-suite/projectView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import * as assert from "assert";
import * as vscode from "vscode";
import {
Commands, contextManager, DependencyExplorer, ProjectNode, WorkspaceNode,
Commands, contextManager, DependencyExplorer, Jdtls, ProjectNode, WorkspaceNode,
} from "../../extension.bundle";
import { setupTestEnv } from "../shared";

Expand Down Expand Up @@ -44,6 +44,43 @@ suite("Multiple Project View Tests", () => {
assert.ok(updatedRoots?.every(root => root instanceof WorkspaceNode), "All roots should remain workspace nodes");
});

test("Hides workspace folders without Java projects when non-Java resources are hidden", async function() {
const configuration = vscode.workspace.getConfiguration("java.project.explorer");
const originalWorkspaceValue = configuration.inspect<boolean>("showNonJavaResources")?.workspaceValue;

await configuration.update("showNonJavaResources", false, vscode.ConfigurationTarget.Workspace);
try {
await vscode.commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH);

const folders = vscode.workspace.workspaceFolders || [];
const expectedNames: string[] = [];
for (const folder of folders) {
if ((await Jdtls.getProjects(folder.uri.toString())).length > 0) {
expectedNames.push(folder.name);
}
}

assert.ok(expectedNames.includes("maven"), "The Maven workspace folder should contain a Java project");
assert.ok(!expectedNames.includes("non-java"), "The non-Java fixture should not contain a Java project");

const explorer = DependencyExplorer.getInstance(contextManager.context);
const roots = await explorer.dataProvider.getChildren();
assert.deepStrictEqual(
roots?.map(root => root.getDisplayName()),
expectedNames,
"Only workspace folders containing Java projects should be shown",
);
assert.ok(roots?.every(root => root instanceof WorkspaceNode), "All roots should remain workspace nodes");
} finally {
await configuration.update(
"showNonJavaResources",
originalWorkspaceValue,
vscode.ConfigurationTarget.Workspace,
);
await vscode.commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH);
}
});

test("Does not add project roots while cached multi-root roots are stale", async function() {
const explorer = DependencyExplorer.getInstance(contextManager.context);
const roots = await explorer.dataProvider.getChildren();
Expand Down