More code moved from jdt.ls.extension to jdt.ls.commons
jdt.ls extension reduced to a simple wrapper that forwards requests to commons implementation.
This commit is contained in:
@@ -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.tooling.ls.eclipse.commons;
|
||||
|
||||
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 + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,10 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.ls.eclipse.commons;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -29,4 +32,10 @@ public interface STS4LanguageClient extends LanguageClient {
|
||||
// TODO: @JsonRequest("sts/moveCursor")
|
||||
// CompletableFuture<Object> moveCursor(CursorMovement cursorMovement);
|
||||
|
||||
@JsonRequest("sts/addClasspathListener")
|
||||
CompletableFuture<Object> addClasspathListener(ClasspathListenerParams params);
|
||||
|
||||
@JsonRequest("sts/removeClasspathListener")
|
||||
CompletableFuture<Object> removeClasspathListener(ClasspathListenerParams classpathListenerParams);
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
@@ -42,6 +43,7 @@ import org.eclipse.ui.texteditor.AbstractTextEditor;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4LanguageClient {
|
||||
@@ -174,5 +176,17 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Object> addClasspathListener(ClasspathListenerParams params) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Object> removeClasspathListener(ClasspathListenerParams classpathListenerParams) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@ Bundle-SymbolicName: org.springframework.tooling.jdt.ls.commons
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Automatic-Module-Name: org.springframework.tooling.jdt.ls.commons
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.eclipse.jdt.ls.core,
|
||||
org.eclipse.core.runtime,
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
org.eclipse.jdt.core,
|
||||
org.eclipse.core.resources
|
||||
Export-Package: org.springframework.tooling.jdt.ls.commons,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.springframework.tooling.jdt.ls.commons.classpath;
|
||||
|
||||
public interface ClientCommandExecutor {
|
||||
Object executeClientCommand(String id, Object... params);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.classpath;
|
||||
|
||||
import static org.springframework.tooling.jdt.ls.commons.Logger.log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ClasspathListenerManager.ClasspathListener;
|
||||
|
||||
/**
|
||||
* {@link ReusableClasspathListenerHandler} is an 'abstracted' version of the jdtls ClasspathListenerHandler.
|
||||
*/
|
||||
public class ReusableClasspathListenerHandler {
|
||||
|
||||
private ClientCommandExecutor conn;
|
||||
|
||||
public ReusableClasspathListenerHandler(ClientCommandExecutor conn) {
|
||||
this.conn = conn;
|
||||
log("Instantiating ReusableClasspathListenerHandler");
|
||||
}
|
||||
|
||||
class Subscribptions {
|
||||
|
||||
private Map<String, ClasspathListenerManager> subscribers = null;
|
||||
|
||||
public synchronized void subscribe(String callbackCommandId) {
|
||||
Logger.log("subscribing to classpath changes: " + callbackCommandId);
|
||||
if (subscribers==null) {
|
||||
subscribers = new HashMap<>(1);
|
||||
}
|
||||
subscribers.computeIfAbsent(callbackCommandId, (cid) -> new ClasspathListenerManager(new ClasspathListener() {
|
||||
@Override
|
||||
public void classpathChanged(IJavaProject jp) {
|
||||
sendNotification(callbackCommandId, jp);
|
||||
}
|
||||
}, true));
|
||||
Logger.log("subsribers = " + subscribers.keySet());
|
||||
}
|
||||
|
||||
private void sendNotification(String callbackCommandId, IJavaProject jp) {
|
||||
//TODO: make one Job to accumulate all requested notification and work more efficiently by batching
|
||||
// and avoiding multiple executions of duplicated requests.
|
||||
new Job("SendClasspath notification") {
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
log("Classpath changed " + jp.getElementName());
|
||||
String project = jp.getProject().getLocationURI().toString();
|
||||
boolean deleted = !jp.exists();
|
||||
// JavaClientConnection conn = JavaLanguageServerPlugin.getInstance().getClientConnection();
|
||||
String projectName = jp.getElementName();
|
||||
|
||||
Classpath classpath = null;
|
||||
if (!deleted) {
|
||||
try {
|
||||
classpath = ClasspathUtil.resolve(jp);
|
||||
} catch (Exception e) {
|
||||
Logger.log(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Logger.log("executing callback "+callbackCommandId+" "+projectName+" "+deleted+" "+(classpath==null ? "" : classpath.getEntries().size()));
|
||||
conn.executeClientCommand(callbackCommandId, project, projectName, deleted, classpath);
|
||||
Logger.log("executing callback "+callbackCommandId+" SUCCESS");
|
||||
} catch (Exception e) {
|
||||
Logger.log("executing callback "+callbackCommandId+" FAILED");
|
||||
Logger.log(e);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
.schedule();
|
||||
}
|
||||
|
||||
public synchronized void unsubscribe(String callbackCommandId) {
|
||||
Logger.log("unsubscribing from classpath changes: " + callbackCommandId);
|
||||
if (subscribers != null) {
|
||||
ClasspathListenerManager mgr = subscribers.remove(callbackCommandId);
|
||||
if (mgr!=null) {
|
||||
mgr.dispose();
|
||||
}
|
||||
if (subscribers.isEmpty()) {
|
||||
subscribers = null;
|
||||
}
|
||||
}
|
||||
Logger.log("subsribers = " + subscribers.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
private Subscribptions subscribptions = new Subscribptions();
|
||||
|
||||
public Object removeClasspathListener(String callbackCommandId) {
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId);
|
||||
subscribptions.unsubscribe(callbackCommandId);
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId + " => OK");
|
||||
return "ok";
|
||||
}
|
||||
|
||||
public Object addClasspathListener(String callbackCommandId) {
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId);
|
||||
subscribptions.subscribe(callbackCommandId);
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId + " => OK");
|
||||
return "ok";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,110 +12,38 @@ package org.springframework.tooling.jdt.ls.extension;
|
||||
|
||||
import static org.springframework.tooling.jdt.ls.commons.Logger.log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.ls.core.internal.IDelegateCommandHandler;
|
||||
import org.eclipse.jdt.ls.core.internal.JavaClientConnection;
|
||||
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
|
||||
import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.Classpath;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ClasspathListenerManager;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ClasspathListenerManager.ClasspathListener;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ClasspathUtil;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ClientCommandExecutor;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ReusableClasspathListenerHandler;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class ClasspathListenerHandler implements IDelegateCommandHandler {
|
||||
|
||||
static final boolean isSupported = checkSupported();
|
||||
private static boolean checkSupported() {
|
||||
private static ReusableClasspathListenerHandler handlerImpl = checkSupported();
|
||||
private static ReusableClasspathListenerHandler checkSupported() {
|
||||
try {
|
||||
JavaClientConnection.class.getMethod("executeClientCommand", String.class, Object[].class);
|
||||
return true;
|
||||
return new ReusableClasspathListenerHandler(new ClientCommandExecutor() {
|
||||
@Override
|
||||
public Object executeClientCommand(String id, Object... params) {
|
||||
return JavaLanguageServerPlugin.getInstance().getClientConnection().executeClientCommand(id, params);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Logger.log(e);
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
static class Subscribptions {
|
||||
|
||||
private static Map<String, ClasspathListenerManager> subscribers = null;
|
||||
|
||||
public synchronized void subscribe(String callbackCommandId) {
|
||||
Logger.log("subscribing to classpath changes: " + callbackCommandId);
|
||||
if (subscribers==null) {
|
||||
subscribers = new HashMap<>(1);
|
||||
}
|
||||
subscribers.computeIfAbsent(callbackCommandId, (cid) -> new ClasspathListenerManager(new ClasspathListener() {
|
||||
@Override
|
||||
public void classpathChanged(IJavaProject jp) {
|
||||
sendNotification(callbackCommandId, jp);
|
||||
}
|
||||
}, true));
|
||||
Logger.log("subsribers = " + subscribers.keySet());
|
||||
}
|
||||
|
||||
private void sendNotification(String callbackCommandId, IJavaProject jp) {
|
||||
//TODO: make one Job to accumulate all requested notification and work more efficiently by batching
|
||||
// and avoiding multiple executions of duplicated requests.
|
||||
new Job("SendClasspath notification") {
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
log("Classpath changed " + jp.getElementName());
|
||||
String project = jp.getProject().getLocationURI().toString();
|
||||
boolean deleted = !jp.exists();
|
||||
JavaClientConnection conn = JavaLanguageServerPlugin.getInstance().getClientConnection();
|
||||
String projectName = jp.getElementName();
|
||||
|
||||
Classpath classpath = null;
|
||||
if (!deleted) {
|
||||
try {
|
||||
classpath = ClasspathUtil.resolve(jp);
|
||||
} catch (Exception e) {
|
||||
Logger.log(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Logger.log("executing callback "+callbackCommandId+" "+projectName+" "+deleted+" "+(classpath==null ? "" : classpath.getEntries().size()));
|
||||
conn.executeClientCommand(callbackCommandId, project, projectName, deleted, classpath);
|
||||
Logger.log("executing callback "+callbackCommandId+" SUCCESS");
|
||||
} catch (Exception e) {
|
||||
Logger.log("executing callback "+callbackCommandId+" FAILED");
|
||||
Logger.log(e);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
.schedule();
|
||||
}
|
||||
|
||||
public synchronized void unsubscribe(String callbackCommandId) {
|
||||
Logger.log("unsubscribing from classpath changes: " + callbackCommandId);
|
||||
if (subscribers != null) {
|
||||
ClasspathListenerManager mgr = subscribers.remove(callbackCommandId);
|
||||
if (mgr!=null) {
|
||||
mgr.dispose();
|
||||
}
|
||||
if (subscribers.isEmpty()) {
|
||||
subscribers = null;
|
||||
}
|
||||
}
|
||||
Logger.log("subsribers = " + subscribers.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
private static Subscribptions subscribptions = new Subscribptions();
|
||||
|
||||
@Override
|
||||
public Object executeCommand(String commandId, List<Object> arguments, IProgressMonitor monitor) throws Exception {
|
||||
if (!isSupported) {
|
||||
if (handlerImpl==null) {
|
||||
throw new UnsupportedOperationException("Command '"+commandId+"' not supported on older versions of JDT Language Server");
|
||||
}
|
||||
log("ClasspathListenerHandler executeCommand " + commandId + ", " + arguments);
|
||||
@@ -130,15 +58,13 @@ public class ClasspathListenerHandler implements IDelegateCommandHandler {
|
||||
}
|
||||
|
||||
private Object removeClasspathListener(String callbackCommandId) {
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId);
|
||||
subscribptions.unsubscribe(callbackCommandId);
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId + " => OK");
|
||||
return "ok";
|
||||
log("ClasspathListenerHandler removeClasspathListener " + callbackCommandId);
|
||||
return handlerImpl.removeClasspathListener(callbackCommandId);
|
||||
}
|
||||
|
||||
private Object addClasspathListener(String callbackCommandId) {
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId);
|
||||
subscribptions.subscribe(callbackCommandId);
|
||||
handlerImpl.addClasspathListener(callbackCommandId);
|
||||
log("ClasspathListenerHandler addClasspathListener " + callbackCommandId + " => OK");
|
||||
return "ok";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user