Skip to content

Commit f0a133c

Browse files
committed
Add more features to the Java Dashboard
Signed-off-by: Thomas Mäder <t.s.maeder@gmail.com>
1 parent 5eab51e commit f0a133c

File tree

11 files changed

+221
-68
lines changed

11 files changed

+221
-68
lines changed

icons/icon24.png

1.12 KB
Loading

icons/java-svgrepo-com.svg

Lines changed: 13 additions & 0 deletions
Loading

package.json

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,7 +1752,21 @@
17521752
"command": "java.action.showExtendedOutline",
17531753
"title": "%java.action.showExtendedOutline%",
17541754
"category": "Java"
1755-
}
1755+
},
1756+
{
1757+
"command": "java.dashboard.refresh",
1758+
"category": "Java",
1759+
"title": "Refresh",
1760+
"icon": "$(refresh)",
1761+
"when": "java:dashboard == true"
1762+
},
1763+
{
1764+
"command": "java.dashboard.dumpState",
1765+
"category": "Java",
1766+
"title": "Dump State",
1767+
"icon": "$(json)",
1768+
"when": "java:dashboard == true"
1769+
}
17561770
],
17571771
"keybindings": [
17581772
{
@@ -1928,6 +1942,16 @@
19281942
"command": "java.action.showSubtypeHierarchy",
19291943
"group": "navigation@1",
19301944
"when": "view == references-view.tree && reference-list.hasResult && reference-list.source == javaTypeHierarchy"
1945+
},
1946+
{
1947+
"command": "java.dashboard.refresh",
1948+
"group": "navigation",
1949+
"when": "view == java.dashboard"
1950+
},
1951+
{
1952+
"command": "java.dashboard.dumpState",
1953+
"group": "navigation",
1954+
"when": "view == java.dashboard"
19311955
}
19321956
],
19331957
"view/item/context": [
@@ -1938,22 +1962,13 @@
19381962
}
19391963
]
19401964
},
1941-
"viewsContainers": {
1942-
"activitybar": [
1943-
{
1944-
"id": "vscode-java-container",
1945-
"title": "Java",
1946-
"icon": "icons/icon128.png"
1947-
}
1948-
]
1949-
},
19501965
"views": {
1951-
"vscode-java-container": [
1966+
"explorer": [
19521967
{
19531968
"type": "webview",
1954-
"id": "vscode-java-dashboard",
1955-
"name": "Dashboard",
1956-
"icon": "icons/icons128.png"
1969+
"id": "java.dashboard",
1970+
"name": "Java Dashboard",
1971+
"icon": "icons/java-svgrepo-com.svg"
19571972
}
19581973
]
19591974
}

src/commands.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ export namespace Commands {
366366
*/
367367
export const SHOW_EXTEND_OUTLINE = 'java.action.showExtendedOutline';
368368

369+
/**
370+
* Get diagnostic info command in jdt.ls
371+
*/
372+
export const GET_DIAGNOSTIC_INFO = 'java.getDiagnosticInfo';
369373
}
370374

371375
/**

src/dashboard/dashboard.ts

Lines changed: 95 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,57 @@
11
import { prepareExecutable } from '../javaServerStarter';
2-
import { getComputedJavaConfig, getExecutable } from '../extension';
2+
import { getComputedJavaConfig, getExecutable, getWorkspacePath } from '../extension';
33
import * as fs from 'fs';
44
import * as path from 'path';
55
import * as vscode from 'vscode';
66
import { getNonce, getUri } from '../webviewUtils';
7-
import { InitializeMessage, JVM, SettingChangedMessage } from '../webviewProtocol/toDashboard';
8-
import { isLombokSupportEnabled } from '../lombokSupport';
7+
import { DashboardState, DiagnosticInfo, JVM, UpdateMessage } from '../webviewProtocol/toDashboard';
8+
import { isLombokSupportEnabled, Lombok } from '../lombokSupport';
9+
import { Commands } from '../commands';
10+
import { apiManager } from '../apiManager';
911

12+
const currentState: DashboardState = {
13+
};
14+
15+
export namespace Dashboard {
16+
export function initialize(context: vscode.ExtensionContext): void {
17+
console.log('registering dashboard webview provider');
18+
let webview: vscode.Webview;
19+
20+
context.subscriptions.push(vscode.window.registerWebviewViewProvider('java.dashboard', {
21+
resolveWebviewView: async function (webviewView: vscode.WebviewView, webviewContext: vscode.WebviewViewResolveContext, token: vscode.CancellationToken): Promise<void> {
22+
vscode.commands.executeCommand('setContext', 'java:dashboard', true);
23+
webview = webviewView.webview;
24+
webviewView.webview.options = {
25+
enableScripts: true,
26+
enableCommandUris: true,
27+
localResourceRoots: [context.extensionUri]
28+
};
29+
30+
webviewView.webview.html = await getWebviewContent(webviewView.webview, context);
31+
webviewView.onDidDispose(() => {
32+
vscode.commands.executeCommand('setContext', 'java:dashboard', false);
33+
});
34+
}
35+
}));
36+
37+
context.subscriptions.push(vscode.commands.registerCommand('java.dashboard.refresh', async () => {
38+
refreshLSInfo(webview);
39+
}));
40+
41+
context.subscriptions.push(vscode.commands.registerCommand('java.dashboard.revealFileInOS', async (arg: { path: string }) => {
42+
await vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(arg.path));
43+
}));
44+
45+
context.subscriptions.push(vscode.commands.registerCommand('java.dashboard.dumpState', async () => {
46+
await vscode.workspace.openTextDocument({
47+
language: 'json',
48+
content: JSON.stringify(currentState, null, 2)
49+
});
50+
}));
51+
52+
console.log('registered dashboard webview provider');
53+
}
54+
}
1055

1156
async function getJvms(): Promise<JVM[]> {
1257
const config = await getComputedJavaConfig();
@@ -19,10 +64,10 @@ async function getJvms(): Promise<JVM[]> {
1964

2065
}
2166

22-
export function getWebviewContent(webview: vscode.Webview, extensionUri: vscode.Uri) {
67+
function getWebviewContent(webview: vscode.Webview, context: vscode.ExtensionContext) {
2368
setWebviewMessageListener(webview);
2469

25-
const scriptUri = getUri(webview, extensionUri, [
70+
const scriptUri = getUri(webview, context.extensionUri, [
2671
"dist",
2772
"dashboard.js",
2873
]);
@@ -45,30 +90,66 @@ export function getWebviewContent(webview: vscode.Webview, extensionUri: vscode.
4590
</html>
4691
`;
4792
}
93+
async function refreshLSInfo(webview: vscode.Webview): Promise<void> {
94+
try {
95+
vscode.commands.executeCommand<DiagnosticInfo>(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.GET_DIAGNOSTIC_INFO).then(info => {
96+
currentState.diagnosticInfo = info;
97+
const msg: UpdateMessage = {
98+
type: "update",
99+
diagnosticInfo: info
100+
};
101+
webview.postMessage(msg);
102+
});
103+
} catch (e) {
104+
console.error('Failed to get diagnostic info', e);
105+
}
106+
}
107+
108+
function setWebviewMessageListener(webview: vscode.Webview) {
48109

49-
function setWebviewMessageListener(webview: vscode.Webview) {
50110
vscode.workspace.onDidChangeConfiguration(e => {
51111
if (e.affectsConfiguration('java.jdt.ls.lombokSupport.enabled')) {
52-
const msg: SettingChangedMessage = {
53-
type: "settingsChanged",
112+
currentState.lombokEnabled = isLombokSupportEnabled();
113+
const msg: UpdateMessage = {
114+
type: "update",
54115
lombokEnabled: isLombokSupportEnabled()
55-
}
116+
};
56117
webview.postMessage(msg);
57118
}
119+
if (e.affectsConfiguration('java')) {
120+
setTimeout(() => refreshLSInfo(webview), 1000); // wait for LS to pick up the config change
121+
}
58122
});
59123

60124
webview.onDidReceiveMessage(
61125
async (message: any) => {
62126
const command = message.command;
63127
switch (command) {
64-
case "webviewReady":
65-
const message: InitializeMessage = {
66-
type: "initialize",
67-
jvms: await getJvms(),
68-
lombokEnabled: isLombokSupportEnabled()
128+
case "webviewReady": {
129+
await apiManager.getApiInstance().serverReady;
130+
currentState.lombokEnabled = isLombokSupportEnabled();
131+
currentState.activeLombokPath = Lombok.getActiveLombokPath();
132+
currentState.workspacePath = getWorkspacePath();
133+
const message: UpdateMessage = {
134+
type: "update",
135+
lombokEnabled: isLombokSupportEnabled(),
136+
activeLombokPath: Lombok.getActiveLombokPath(),
137+
workspacePath: getWorkspacePath(),
69138
};
70139
await webview.postMessage(message);
140+
getJvms().then(jvms => {
141+
currentState.jvms = jvms;
142+
const msg: UpdateMessage = {
143+
type: "update",
144+
jvms: jvms
145+
};
146+
147+
webview.postMessage(msg);
148+
});
149+
150+
refreshLSInfo(webview);
71151
break;
152+
}
72153
}
73154
}
74155
);

src/extension.ts

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as semver from 'semver';
99
import { CodeActionContext, commands, CompletionItem, ConfigurationTarget, Diagnostic, env, EventEmitter, ExtensionContext, extensions,
1010
IndentAction, InputBoxOptions, languages, Location, MarkdownString, QuickPickItemKind, Range, RelativePattern,
1111
SnippetString, SnippetTextEdit, TextDocument, TextEditorRevealType, UIKind, Uri, version, ViewColumn,
12+
Webview,
1213
WebviewView, WebviewViewResolveContext, window, workspace, WorkspaceConfiguration, WorkspaceEdit } from 'vscode';
1314
import { CancellationToken, CodeActionParams, CodeActionRequest, CodeActionResolveRequest, Command, CompletionRequest, DidChangeConfigurationNotification, ExecuteCommandParams, ExecuteCommandRequest, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient';
1415
import { Executable, LanguageClient } from 'vscode-languageclient/node';
@@ -43,7 +44,7 @@ import { pasteFile } from './pasteAction';
4344
import { ServerStatusKind } from './serverStatus';
4445
import { TelemetryService } from '@redhat-developer/vscode-redhat-telemetry/lib/node';
4546
import { Deferred } from './promiseUtil';
46-
import { getWebviewContent } from './dashboard/dashboard';
47+
import { Dashboard } from './dashboard/dashboard';
4748

4849
const syntaxClient: SyntaxLanguageClient = new SyntaxLanguageClient();
4950
const standardClient: StandardLanguageClient = new StandardLanguageClient();
@@ -129,20 +130,11 @@ export function fixJdtLinksInDocumentation(oldDocumentation: MarkdownString): Ma
129130
}
130131

131132
export async function activate(context: ExtensionContext): Promise<ExtensionAPI> {
132-
console.log('registering webview provider');
133-
context.subscriptions.push(window.registerWebviewViewProvider('vscode-java-dashboard', {
134-
resolveWebviewView: async function (webviewView: WebviewView, webviewContext: WebviewViewResolveContext, token: CancellationToken): Promise<void> {
135-
136-
webviewView.webview.options = {
137-
enableScripts: true,
138-
enableCommandUris: true,
139-
localResourceRoots: [context.extensionUri]
140-
};
141-
142-
webviewView.webview.html = await getWebviewContent(webviewView.webview, context.extensionUri);
143-
}
144-
}));
145-
console.log('registered webview provider');
133+
storagePath = context.storagePath;
134+
if (!storagePath) {
135+
storagePath = getTempWorkspace();
136+
}
137+
Dashboard.initialize(context);
146138

147139
await loadSupportedJreNames(context);
148140
context.subscriptions.push(commands.registerCommand(Commands.FILESEXPLORER_ONPASTE, async () => {
@@ -161,16 +153,13 @@ export async function activate(context: ExtensionContext): Promise<ExtensionAPI>
161153
markdownPreviewProvider.show(context.asAbsolutePath(path.join('document', `_java.notCoveredExecution.md`)), 'Not Covered Maven Plugin Execution', "", context);
162154
}));
163155

164-
storagePath = context.storagePath;
165156
context.subscriptions.push(commands.registerCommand(Commands.METADATA_FILES_GENERATION, async () => {
166157
markdownPreviewProvider.show(context.asAbsolutePath(path.join('document', `_java.metadataFilesGeneration.md`)), 'Metadata Files Generation', "", context);
167158
}));
168159
context.subscriptions.push(commands.registerCommand(Commands.LEARN_MORE_ABOUT_CLEAN_UPS, async () => {
169160
markdownPreviewProvider.show(context.asAbsolutePath(path.join('document', `${Commands.LEARN_MORE_ABOUT_CLEAN_UPS}.md`)), 'Java Clean Ups', "java-clean-ups", context);
170161
}));
171-
if (!storagePath) {
172-
storagePath = getTempWorkspace();
173-
}
162+
174163
const workspacePath = path.resolve(`${storagePath}/jdt_ws`);
175164
clientLogFile = path.join(storagePath, 'client.log');
176165
const cleanWorkspaceExists = fs.existsSync(path.join(workspacePath, cleanWorkspaceFileName));
@@ -894,18 +883,22 @@ async function cleanSharedIndexes(context: ExtensionContext) {
894883
}
895884

896885
function openServerLogFile(storagePath, column: ViewColumn = ViewColumn.Active): Thenable<boolean> {
897-
const workspacePath = getWorkspacePath(storagePath);
886+
const workspacePath = computeWorkspacePath(storagePath);
898887
const serverLogFile = path.join(workspacePath, '.metadata', '.log');
899888
return openLogFile(serverLogFile, 'Could not open Java Language Server log file', column);
900889
}
901890

902-
function getWorkspacePath(storagePath: any) {
891+
function computeWorkspacePath(storagePath: any) {
903892
return path.join(storagePath, apiManager.getApiInstance().serverMode === ServerMode.lightWeight ? 'ss_ws' : 'jdt_ws');
904893
}
905894

895+
export function getWorkspacePath() {
896+
return computeWorkspacePath(storagePath);
897+
}
898+
906899
function openRollingServerLogFile(storagePath, filename, column: ViewColumn = ViewColumn.Active): Thenable<boolean> {
907900
return new Promise((resolve) => {
908-
const workspacePath = getWorkspacePath(storagePath);
901+
const workspacePath = computeWorkspacePath(storagePath);
909902
const dirname = path.join(workspacePath, '.metadata');
910903

911904
// find out the newest one

src/lombokSupport.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ let isLombokCommandInitialized: boolean = false;
3030
let isExtensionLombok: boolean = false; // whether use extension's Lombok or not
3131
let projectLombokPath: string = undefined; // the project's Lombok classpath
3232

33+
export namespace Lombok {
34+
35+
export function getActiveLombokPath(): string | undefined {
36+
return activeLombokPath;
37+
}
38+
}
3339
export function isLombokSupportEnabled(): boolean {
3440
return vscode.workspace.getConfiguration().get("java.jdt.ls.lombokSupport.enabled");
3541
}

0 commit comments

Comments
 (0)