Initial implementation for adding classpath listener
This commit is contained in:
@@ -16,6 +16,8 @@ import java.util.concurrent.CompletableFuture;
|
||||
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
|
||||
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
|
||||
import org.eclipse.lsp4j.services.LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerResponse;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit.CursorMovement;
|
||||
|
||||
/**
|
||||
@@ -39,4 +41,7 @@ public interface STS4LanguageClient extends LanguageClient {
|
||||
|
||||
@JsonRequest("sts/project")
|
||||
CompletableFuture<ProjectResponse> project(String uri);
|
||||
|
||||
@JsonRequest("sts/addClasspathListener")
|
||||
CompletableFuture<ClasspathListenerResponse> addClasspathListener(ClasspathListenerParams params);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.jdt.ls;
|
||||
|
||||
public interface ClasspathListener {
|
||||
|
||||
void changed(String projectUri, boolean deleted);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.jdt.ls;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.eclipse.lsp4j.Registration;
|
||||
import org.eclipse.lsp4j.RegistrationParams;
|
||||
import org.eclipse.lsp4j.Unregistration;
|
||||
import org.eclipse.lsp4j.UnregistrationParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import reactor.core.Disposable;
|
||||
|
||||
public class ClasspathListenerManager {
|
||||
|
||||
private static final String WORKSPACE_EXECUTE_COMMAND = "workspace/executeCommand";
|
||||
private int commandIdCounter = 0;
|
||||
private SimpleLanguageServer server;
|
||||
|
||||
public ClasspathListenerManager(SimpleLanguageServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public Disposable addClasspathListener(ClasspathListener classpathListener) {
|
||||
// TODO:
|
||||
// 1. register callback command handler in SimpleLanguageServer
|
||||
// 2. call the client to ask it to call that callback
|
||||
// 3. register the callback command with the client
|
||||
String callbackCommandId = "sts4.classpath." + (commandIdCounter++);
|
||||
String registrationId = UUID.randomUUID().toString();
|
||||
|
||||
RegistrationParams params = new RegistrationParams(ImmutableList.of(
|
||||
new Registration(registrationId,
|
||||
WORKSPACE_EXECUTE_COMMAND,
|
||||
ImmutableMap.of("commands", ImmutableList.of(callbackCommandId))
|
||||
)
|
||||
));
|
||||
server.getClient().registerCapability(params);
|
||||
return () -> {
|
||||
this.server.getClient().unregisterCapability(new UnregistrationParams(ImmutableList.of(
|
||||
new Unregistration(registrationId, WORKSPACE_EXECUTE_COMMAND)
|
||||
)));
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.jdt.ls;
|
||||
|
||||
public class ClasspathListenerParams {
|
||||
|
||||
private String callbackCommandId;
|
||||
|
||||
public ClasspathListenerParams(String callbackCommandId) {
|
||||
super();
|
||||
this.callbackCommandId = callbackCommandId;
|
||||
}
|
||||
|
||||
public String getCallbackCommandId() {
|
||||
return callbackCommandId;
|
||||
}
|
||||
|
||||
public void setCallbackCommandId(String callbackCommandId) {
|
||||
this.callbackCommandId = callbackCommandId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClasspathListenerParams [callbackCommandId=" + callbackCommandId + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.jdt.ls;
|
||||
|
||||
public class ClasspathListenerResponse {
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -54,6 +55,8 @@ import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter.LazyCompletionResolver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit;
|
||||
@@ -74,6 +77,7 @@ import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import reactor.core.Disposable;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
@@ -128,7 +132,10 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
|
||||
private Runnable shutdownHandler;
|
||||
|
||||
private Map<String, ExecuteCommandHandler> commands = new HashMap<>();
|
||||
|
||||
private AsyncRunner async = new AsyncRunner();
|
||||
private ClasspathListenerManager classpathListenerManager;
|
||||
|
||||
@Override
|
||||
public void connect(LanguageClient _client) {
|
||||
@@ -297,6 +304,18 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
return deflt;
|
||||
}
|
||||
|
||||
public Disposable onCommand(String id, ExecuteCommandHandler commandHandler) {
|
||||
synchronized (commands) {
|
||||
Assert.isLegal(!commands.containsKey(id));
|
||||
commands.put(id, commandHandler);
|
||||
}
|
||||
return () -> {
|
||||
synchronized (commands) {
|
||||
commands.remove(id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void onError(String message, Throwable error) {
|
||||
LanguageClient cl = this.client;
|
||||
if (cl != null) {
|
||||
@@ -618,4 +637,11 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
public AsyncRunner getAsync() {
|
||||
return this.async;
|
||||
}
|
||||
|
||||
public synchronized Disposable addClasspathListener(ClasspathListener classpathListener) {
|
||||
if (classpathListenerManager == null) {
|
||||
classpathListenerManager = new ClasspathListenerManager(this);
|
||||
}
|
||||
return classpathListenerManager.addClasspathListener(classpathListener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,8 @@ import org.springframework.ide.vscode.commons.languageserver.ProgressParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ProjectResponse;
|
||||
import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListenerResponse;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit.CursorMovement;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.LanguageServerTestListener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.Settings;
|
||||
@@ -305,6 +307,12 @@ public class LanguageServerHarness<S extends SimpleLanguageServerWrapper> {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ClasspathListenerResponse> addClasspathListener(
|
||||
ClasspathListenerParams params) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.jdt.ls.extension;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jdt.core.ElementChangedEvent;
|
||||
import org.eclipse.jdt.core.IElementChangedListener;
|
||||
import org.eclipse.jdt.core.IJavaElement;
|
||||
import org.eclipse.jdt.core.IJavaElementDelta;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
|
||||
/**
|
||||
* An instance of this class provides a means to register
|
||||
* listeners that get notified when classpath for a IJavaProject
|
||||
* changes.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class ClasspathListenerManager {
|
||||
|
||||
public interface ClasspathListener {
|
||||
public abstract void classpathChanged(IJavaProject jp);
|
||||
}
|
||||
|
||||
private class MyListener implements IElementChangedListener {
|
||||
|
||||
@Override
|
||||
public void elementChanged(ElementChangedEvent event) {
|
||||
visit(event.getDelta());
|
||||
}
|
||||
|
||||
private void visit(IJavaElementDelta delta) {
|
||||
IJavaElement el = delta.getElement();
|
||||
switch (el.getElementType()) {
|
||||
case IJavaElement.JAVA_MODEL:
|
||||
visitChildren(delta);
|
||||
break;
|
||||
case IJavaElement.JAVA_PROJECT:
|
||||
if (isClasspathChanged(delta.getFlags())) {
|
||||
listener.classpathChanged((IJavaProject)el);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isClasspathChanged(int flags) {
|
||||
return 0!= (flags & (
|
||||
IJavaElementDelta.F_CLASSPATH_CHANGED |
|
||||
IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED
|
||||
));
|
||||
}
|
||||
|
||||
public void visitChildren(IJavaElementDelta delta) {
|
||||
for (IJavaElementDelta c : delta.getAffectedChildren()) {
|
||||
visit(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ClasspathListener listener;
|
||||
private MyListener myListener;
|
||||
|
||||
/**
|
||||
* @param initialEvent If true, events are fired immediately on all existing java
|
||||
* projects, treating the connection of the listener itself as a change event.
|
||||
* This allows clients to become aware of all classpaths from the start and
|
||||
* continually monitor them for changes from that point onward.
|
||||
*/
|
||||
public ClasspathListenerManager(ClasspathListener listener, boolean initialEvent) {
|
||||
this.listener = listener;
|
||||
if (initialEvent) {
|
||||
for (IProject p : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
|
||||
try {
|
||||
if (p.isAccessible() && p.hasNature(JavaCore.NATURE_ID)) {
|
||||
IJavaProject jp = JavaCore.create(p);
|
||||
listener.classpathChanged(jp);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
Logger.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
JavaCore.addElementChangedListener(myListener=new MyListener(), ElementChangedEvent.POST_CHANGE);
|
||||
}
|
||||
|
||||
public ClasspathListenerManager(ClasspathListener listener) {
|
||||
this(listener, false);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (myListener!=null) {
|
||||
JavaCore.removeElementChangedListener(myListener);
|
||||
myListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,13 +31,6 @@ public class ResolveClasspathHandler implements IDelegateCommandHandler {
|
||||
public static final String ENTRY_KIND_SOURCE = "source";
|
||||
public static final String ENTRY_KIND_BINARY = "binary";
|
||||
public static final String OUTPUT_LOCATION = "output_location";
|
||||
|
||||
static {
|
||||
Executors.newCachedThreadPool().execute(() -> {
|
||||
JavaClientConnection client = JavaLanguageServerPlugin.getInstance().getClientConnection();
|
||||
client.executeCommand("say.hello", "Hello from our redhat extension");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.ide.vscode.commons.languageserver.ProjectResponse;
|
||||
import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.ClasspathListener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
|
||||
@@ -47,6 +48,14 @@ public class JdtLsProjectCache implements JavaProjectFinder, ProjectObserver {
|
||||
|
||||
public JdtLsProjectCache(SimpleLanguageServer server) {
|
||||
this.server = server;
|
||||
this.server.addClasspathListener(new ClasspathListener() {
|
||||
|
||||
@Override
|
||||
public void changed(String projectUri, boolean deleted) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user