From c2cf53195614db4bd71ff7660a6276badd1b5769 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Wed, 7 Dec 2016 16:03:54 -0800 Subject: [PATCH] Create custom protocol for simple progress messages --- .../commons-vscode/src/launch-util.ts | 37 ++++++++- .../commons/commons-language-server/pom.xml | 7 -- .../languageserver/LaunguageServerApp.java | 4 +- .../languageserver/ProgressParams.java | 78 +++++++++++++++++++ .../languageserver/STS4LanguageClient.java | 16 ++++ .../util/SimpleLanguageServer.java | 20 ++++- .../language-server-test-harness/pom.xml | 5 ++ .../testharness/LanguageServerHarness.java | 11 ++- .../completion/DocumentEditsTest.java | 5 ++ 9 files changed, 168 insertions(+), 15 deletions(-) create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/ProgressParams.java create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java rename vscode-extensions/commons/{commons-language-server => language-server-test-harness}/src/test/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEditsTest.java (93%) diff --git a/vscode-extensions/commons-vscode/src/launch-util.ts b/vscode-extensions/commons-vscode/src/launch-util.ts index 949f245b3..5cddcd35d 100644 --- a/vscode-extensions/commons-vscode/src/launch-util.ts +++ b/vscode-extensions/commons-vscode/src/launch-util.ts @@ -11,7 +11,7 @@ import PortFinder = require('portfinder'); import * as Net from 'net'; import * as ChildProcess from 'child_process'; import {LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, StreamInfo} from 'vscode-languageclient'; -import {TextDocument, OutputChannel} from 'vscode'; +import {TextDocument, OutputChannel, Disposable, window} from 'vscode'; PortFinder.basePort = 45556; @@ -104,11 +104,17 @@ export function activate(options : ActivatorOptions, context: VSCode.ExtensionCo let client = new LanguageClient(options.extensionId, options.extensionId, createServer, clientOptions ); + let progressService = new ProgressService(); + client.onNotification({method: "sts/progress"}, (params : ProgressParams) => { + log("progress: "+JSON.stringify(params)); + progressService.handle(params); + }); let disposable = client.start(); // Push the disposable to the context's subscriptions so that the // client can be deactivated on extension deactivation context.subscriptions.push(disposable); + context.subscriptions.push(progressService); }); } @@ -158,4 +164,33 @@ function correctBinname(binname: string) { return binname; } +interface ProgressParams { + id: string + statusMsg?: string +} +class ProgressService { + + private status = new Map(); + + handle(params : ProgressParams) { + let oldMessage = this.status.get(params.id); + if (oldMessage) { + oldMessage.dispose(); + } + if (params.statusMsg) { + let newMessage = window.setStatusBarMessage(params.statusMsg); + this.status.set(params.id, newMessage); + } + } + + dispose() { + if (this.status) { + for (let d of this.status.values()) { + d.dispose(); + } + } + this.status = null; + } + +} diff --git a/vscode-extensions/commons/commons-language-server/pom.xml b/vscode-extensions/commons/commons-language-server/pom.xml index 295e0601d..65fcbdb79 100644 --- a/vscode-extensions/commons/commons-language-server/pom.xml +++ b/vscode-extensions/commons/commons-language-server/pom.xml @@ -65,13 +65,6 @@ reactor-core ${reactor-version} - - - org.springframework.ide.vscode - language-server-test-harness - ${project.version} - test - diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java index 3dcac3325..e86456ce3 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LaunguageServerApp.java @@ -144,8 +144,8 @@ public abstract class LaunguageServerApp { } }; }; - Launcher launcher = Launcher.createLauncher(server, - LanguageClient.class, + Launcher launcher = Launcher.createLauncher(server, + STS4LanguageClient.class, connection.in, connection.out, executor, diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/ProgressParams.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/ProgressParams.java new file mode 100644 index 000000000..a9f867700 --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/ProgressParams.java @@ -0,0 +1,78 @@ +package org.springframework.ide.vscode.commons.languageserver; + +public class ProgressParams { + + /** + * An id representing the enitity for which progress messages are to be shown. + */ + private String id; + + /** + * Updates the current statusMsg associated with a given the id. If null, then the message + * is cleared. + */ + private String statusMsg; + + + public ProgressParams() { + } + + public ProgressParams(String id, String statusMsg) { + super(); + this.id = id; + this.statusMsg = statusMsg; + } + + @Override + public String toString() { + return "ProgressParams [id=" + id + ", statusMsg=" + statusMsg + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((statusMsg == null) ? 0 : statusMsg.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ProgressParams other = (ProgressParams) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (statusMsg == null) { + if (other.statusMsg != null) + return false; + } else if (!statusMsg.equals(other.statusMsg)) + return false; + return true; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getStatusMsg() { + return statusMsg; + } + + public void setStatusMsg(String statusMsg) { + this.statusMsg = statusMsg; + } + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java new file mode 100644 index 000000000..51bed9496 --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java @@ -0,0 +1,16 @@ +package org.springframework.ide.vscode.commons.languageserver; + +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.services.LanguageClient; + +/** + * Some 'custom' extensions to standard LSP {@link LanguageClient}. + * + * @author + */ +public interface STS4LanguageClient extends LanguageClient { + + @JsonNotification("sts/progress") + void progress(ProgressParams progressEvent); + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java index 629a2dd8c..39c6e7124 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java @@ -2,6 +2,7 @@ package org.springframework.ide.vscode.commons.languageserver.util; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -18,12 +19,16 @@ import org.eclipse.lsp4j.ServerCapabilities; import org.eclipse.lsp4j.services.LanguageClient; import org.eclipse.lsp4j.services.LanguageClientAware; import org.eclipse.lsp4j.services.LanguageServer; +import org.springframework.ide.vscode.commons.languageserver.ProgressParams; +import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient; import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector; import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine; import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity; import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem; import org.springframework.ide.vscode.commons.util.Futures; +import reactor.core.publisher.Flux; + /** * Abstract base class to implement LanguageServer. Bits and pieces copied from * the 'JavaLanguageServer' example which seem generally useful / reusable end up in @@ -40,11 +45,20 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl private SimpleWorkspaceService workspace; - private LanguageClient client; + private STS4LanguageClient client; @Override - public void connect(LanguageClient client) { - this.client = client; + public void connect(LanguageClient _client) { + this.client = (STS4LanguageClient) _client; + Flux.range(1, 10) + .delay(Duration.ofMillis(2000)) + .doOnNext((i) -> { + client.progress(new ProgressParams("test-progress", "Progress ["+i+"] ...")); + }) + .doAfterTerminate(() -> { + client.progress(new ProgressParams("test-progress", null)); + }) + .subscribe(); } @Override diff --git a/vscode-extensions/commons/language-server-test-harness/pom.xml b/vscode-extensions/commons/language-server-test-harness/pom.xml index eecb6c90f..9013862a8 100644 --- a/vscode-extensions/commons/language-server-test-harness/pom.xml +++ b/vscode-extensions/commons/language-server-test-harness/pom.xml @@ -24,6 +24,11 @@ commons-java ${project.version} + + org.springframework.ide.vscode + commons-language-server + ${project.version} + junit junit diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java index 6f2daf2de..129eb3842 100644 --- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java +++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java @@ -37,9 +37,10 @@ import org.eclipse.lsp4j.TextDocumentItem; import org.eclipse.lsp4j.TextDocumentPositionParams; import org.eclipse.lsp4j.TextDocumentSyncKind; import org.eclipse.lsp4j.VersionedTextDocumentIdentifier; -import org.eclipse.lsp4j.services.LanguageClient; import org.eclipse.lsp4j.services.LanguageClientAware; import org.eclipse.lsp4j.services.LanguageServer; +import org.springframework.ide.vscode.commons.languageserver.ProgressParams; +import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient; public class LanguageServerHarness { @@ -117,7 +118,7 @@ public class LanguageServerHarness { initParams.setCapabilities(clientCap); initResult = server.initialize(initParams).get(); if (server instanceof LanguageClientAware) { - ((LanguageClientAware) server).connect(new LanguageClient() { + ((LanguageClientAware) server).connect(new STS4LanguageClient() { @Override public void telemetryEvent(Object object) { // TODO Auto-generated method stub @@ -146,6 +147,12 @@ public class LanguageServerHarness { // TODO Auto-generated method stub } + + @Override + public void progress(ProgressParams progressEvent) { + // TODO Auto-generated method stub + + } }); } diff --git a/vscode-extensions/commons/commons-language-server/src/test/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEditsTest.java b/vscode-extensions/commons/language-server-test-harness/src/test/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEditsTest.java similarity index 93% rename from vscode-extensions/commons/commons-language-server/src/test/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEditsTest.java rename to vscode-extensions/commons/language-server-test-harness/src/test/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEditsTest.java index 6b676c507..9f2460a4b 100644 --- a/vscode-extensions/commons/commons-language-server/src/test/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEditsTest.java +++ b/vscode-extensions/commons/language-server-test-harness/src/test/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEditsTest.java @@ -26,6 +26,11 @@ import org.springframework.ide.vscode.languageserver.testharness.LanguageServerH */ public class DocumentEditsTest { + //TODO: it is rather strange to put this test in the language-server-test-harness' project. + // It really belongs in commons-language-server, but unfortunately that makes it impossible + // for the test to use language-server-test-harness (it requires making commons-language-server depend on + // language-server-test-harness which causes a cyclic dependency). + private LanguageServerHarness harness; @Before