Merge branch 'progress'

This commit is contained in:
Kris De Volder
2016-12-08 09:47:31 -08:00
13 changed files with 223 additions and 23 deletions

View File

@@ -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;
@@ -33,6 +33,7 @@ export function activate(options : ActivatorOptions, context: VSCode.ExtensionCo
var log_output = VSCode.window.createOutputChannel(options.extensionId+"-debug-log");
log("Activating '"+options.extensionId+"' extension");
window.showInformationMessage("Activating spring-boot extension!");
function log(msg : string) {
if (log_output) {
@@ -104,11 +105,16 @@ 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) => {
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<String, Disposable>();
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;
}
}

View File

@@ -2,6 +2,7 @@ package org.springframework.ide.vscode.application.properties.metadata;
import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
@@ -10,17 +11,34 @@ public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexPr
private JavaProjectFinder javaProjectFinder;
private SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault());
private ProgressService progressService = (id, msg) -> { /*ignore*/ };
private static int progressIdCt = 0;
public DefaultSpringPropertyIndexProvider(JavaProjectFinder javaProjectFinder) {
this.javaProjectFinder = javaProjectFinder;
}
@Override
public FuzzyMap<PropertyInfo> getIndex(IDocument doc) {
IJavaProject jp = javaProjectFinder.find(doc);
if (jp!=null) {
return indexManager.get(jp);
String progressId = getProgressId();
progressService.progressEvent(progressId, "Indexing Spring Boot Properties...");
try {
IJavaProject jp = javaProjectFinder.find(doc);
if (jp!=null) {
return indexManager.get(jp);
}
} finally {
progressService.progressEvent(progressId, null);
}
return null;
}
private static synchronized String getProgressId() {
return DefaultSpringPropertyIndexProvider.class.getName()+ (progressIdCt++);
}
public void setProgressService(ProgressService progressService) {
this.progressService = progressService;
}
}

View File

@@ -4,7 +4,11 @@ import reactor.core.publisher.Flux;
import reactor.util.function.Tuple2;
public interface IJavaProject extends IJavaElement {
/**
* TypeFilter is deprecated. Should use java.util.funcion.Predicate<IType> instead.
*/
@Deprecated
@FunctionalInterface
public static interface TypeFilter {
boolean accept(IType type);

View File

@@ -65,13 +65,6 @@
<artifactId>reactor-core</artifactId>
<version>${reactor-version}</version>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>language-server-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@@ -144,8 +144,8 @@ public abstract class LaunguageServerApp {
}
};
};
Launcher<LanguageClient> launcher = Launcher.createLauncher(server,
LanguageClient.class,
Launcher<STS4LanguageClient> launcher = Launcher.createLauncher(server,
STS4LanguageClient.class,
connection.in,
connection.out,
executor,

View File

@@ -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;
}
}

View File

@@ -0,0 +1,24 @@
package org.springframework.ide.vscode.commons.languageserver;
@FunctionalInterface
public interface ProgressService {
/**
* Sends a progress event to the LSP client. A taskId is an arbirary id
* that can be chosen by the caller. The purpose of the id is to be a 'unique'
* id for some kind of 'long running job'. Only a single 'statusMsg' is associated
* with a given taskId at any one time. Each event updates the message shown
* to the user replacing the old one.
* <p>
* Updating the message to 'null' erases the previous message without showing
* a new one.
* <p>
* More than one message may be shown simultaneously to the user, if they
* have different taskId.
*
* @param taskId
* @param statusMsg
*/
void progressEvent(String taskId, String statusMsg);
}

View File

@@ -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);
}

View File

@@ -18,6 +18,9 @@ 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.ProgressService;
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;
@@ -40,11 +43,18 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
private SimpleWorkspaceService workspace;
private LanguageClient client;
private STS4LanguageClient client;
private ProgressService progressService = (String taskId, String statusMsg) -> {
STS4LanguageClient client = SimpleLanguageServer.this.client;
if (client!=null) {
client.progress(new ProgressParams(taskId, statusMsg));
}
};
@Override
public void connect(LanguageClient client) {
this.client = client;
public void connect(LanguageClient _client) {
this.client = (STS4LanguageClient) _client;
}
@Override
@@ -177,4 +187,9 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
public LanguageClient getClient() {
return client;
}
public ProgressService getProgressService() {
return progressService;
}
}

View File

@@ -24,6 +24,11 @@
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-language-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@@ -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
}
});
}

View File

@@ -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

View File

@@ -12,14 +12,13 @@ package org.springframework.ide.vscode.boot;
import java.io.IOException;
import org.eclipse.lsp4j.services.LanguageServer;
import org.springframework.ide.vscode.application.properties.metadata.DefaultSpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtilProvider;
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
/**
* Starts up Language Server process
@@ -33,9 +32,10 @@ public class Main {
public static void main(String[] args) throws IOException {
LaunguageServerApp.start(() -> {
JavaProjectFinder javaProjectFinder = JavaProjectFinder.DEFAULT;
SpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
DefaultSpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(javaProjectFinder.find(doc));
LanguageServer server = new BootPropertiesLanguageServer(indexProvider, typeUtilProvider, javaProjectFinder);
SimpleLanguageServer server = new BootPropertiesLanguageServer(indexProvider, typeUtilProvider, javaProjectFinder);
indexProvider.setProgressService(server.getProgressService());
return server;
});
}