Adopt API removal in LSP4E
This commit is contained in:
@@ -12,7 +12,6 @@ package org.springframework.ide.eclipse.boot.dash;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.net.proxy.IProxyService;
|
||||
@@ -33,7 +32,6 @@ import org.springframework.ide.eclipse.boot.core.BootPropertyTester;
|
||||
import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext;
|
||||
import org.springframework.ide.eclipse.boot.dash.liveprocess.CommandInfo;
|
||||
import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveProcessCommandsExecutor;
|
||||
import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveProcessCommandsExecutor.Server;
|
||||
import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext;
|
||||
import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel;
|
||||
import org.springframework.ide.eclipse.boot.dash.model.DefaultBootDashModelContext;
|
||||
@@ -45,7 +43,6 @@ import org.springframework.ide.eclipse.boot.dash.util.RunStateTracker.RunStateLi
|
||||
import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate;
|
||||
import org.springsource.ide.eclipse.commons.livexp.util.Log;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
@@ -194,7 +191,7 @@ public class BootDashActivator extends AbstractUIPlugin {
|
||||
return InstanceScope.INSTANCE.getNode(PLUGIN_ID);
|
||||
}
|
||||
|
||||
private final RunStateListener<ILaunchConfiguration> RUN_STATE_LISTENER = new RunStateListener<ILaunchConfiguration>() {
|
||||
private final RunStateListener<ILaunchConfiguration> RUN_STATE_LISTENER = new RunStateListener<>() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ILaunchConfiguration owner) {
|
||||
@@ -211,9 +208,6 @@ public class BootDashActivator extends AbstractUIPlugin {
|
||||
for (IProcess p : l.getProcesses()) {
|
||||
String pid = p.getAttribute(IProcess.ATTR_PROCESS_ID);
|
||||
if (pid != null) {
|
||||
List<Server> servers = LiveProcessCommandsExecutor.getDefault()
|
||||
.getLanguageServers();
|
||||
|
||||
CommandInfo cmd = new CommandInfo("sts/livedata/connect",
|
||||
Map.of("processKey", pid));
|
||||
|
||||
@@ -221,7 +215,8 @@ public class BootDashActivator extends AbstractUIPlugin {
|
||||
// "VirtualMachine.list()" call may not list the newly created process which means the process is gone and triggers disconnect.
|
||||
// If lifecycle management is enabled the ready state seem to be a great indicator of a boot process fully started.
|
||||
// TODO: explore health endpoint perhaps instead of ready state under Admin endpoint.
|
||||
Flux.fromIterable(servers).flatMap(s -> Mono.delay(Duration.ofMillis(500)).then(s.executeCommand(cmd))).subscribe();
|
||||
// Flux.fromIterable(servers).flatMap(s -> Mono.delay(Duration.ofMillis(500)).then(s.executeCommand(cmd))).subscribe();
|
||||
Mono.delay(Duration.ofMillis(500)).then(LiveProcessCommandsExecutor.getDefault().executeCommand(cmd)).subscribe();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2022 Pivotal Software, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal Software, 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
|
||||
@@ -10,14 +10,17 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.eclipse.boot.dash.liveprocess;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServers;
|
||||
import org.eclipse.lsp4e.LanguageServers.LanguageServerProjectExecutor;
|
||||
import org.eclipse.lsp4e.LanguageServersRegistry;
|
||||
import org.eclipse.lsp4j.ExecuteCommandOptions;
|
||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
@@ -29,46 +32,43 @@ public final class DefaultLiveProcessCommandExecutor implements LiveProcessComma
|
||||
|
||||
private static final String CMD_LIST_PROCESSES = "sts/livedata/listProcesses";
|
||||
|
||||
private class DefaultServer implements Server {
|
||||
private LanguageServer ls;
|
||||
public DefaultServer(LanguageServer ls) {
|
||||
this.ls = ls;
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Flux<CommandInfo> listCommands() {
|
||||
return Mono.fromFuture(ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(
|
||||
CMD_LIST_PROCESSES,
|
||||
ImmutableList.of()
|
||||
)))
|
||||
.flatMapIterable(list -> (List<?>)list)
|
||||
.map(_cmdInfo -> {
|
||||
Map<String,String> map = (Map<String, String>) _cmdInfo;
|
||||
return new CommandInfo(map.get("action"), map);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> executeCommand(CommandInfo cmd) {
|
||||
return Mono.fromRunnable(() -> ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(
|
||||
cmd.command,
|
||||
ImmutableList.of(cmd.info)
|
||||
)));
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Flux<CommandInfo> listCommands() {
|
||||
List<CompletableFuture<List<CommandInfo>>> futures = getLanguageServers().computeAll(ls -> ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(
|
||||
CMD_LIST_PROCESSES,
|
||||
ImmutableList.of()
|
||||
)).thenApply(o -> {
|
||||
if (o instanceof List) {
|
||||
List<?> list = (List<?>) o;
|
||||
return list.stream().map(_cmdInfo -> {
|
||||
Map<String,String> map = (Map<String, String>) _cmdInfo;
|
||||
return new CommandInfo(map.get("action"), map);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
return Collections.<CommandInfo>emptyList();
|
||||
}));
|
||||
Flux<CommandInfo> f = Flux.fromIterable(futures).flatMap(fo -> Mono.fromFuture(fo).flatMapIterable(l -> l));
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getLanguageServers() {
|
||||
return LanguageServiceAccessor.getActiveLanguageServers(cap -> {
|
||||
public Mono<Void> executeCommand(CommandInfo cmd) {
|
||||
return Mono.fromFuture(getLanguageServers().collectAll(ls -> ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(
|
||||
cmd.command,
|
||||
ImmutableList.of(cmd.info)
|
||||
))).thenAccept(null));
|
||||
}
|
||||
|
||||
private LanguageServerProjectExecutor getLanguageServers() {
|
||||
return LanguageServers.forProject(null).withFilter(cap -> {
|
||||
ExecuteCommandOptions commandCap = cap.getExecuteCommandProvider();
|
||||
if (commandCap!=null) {
|
||||
List<String> supportedCommands = commandCap.getCommands();
|
||||
return supportedCommands!=null && supportedCommands.contains(CMD_LIST_PROCESSES);
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.stream()
|
||||
.map(DefaultServer::new)
|
||||
.collect(Collectors.toList());
|
||||
}).withPreferredServer(LanguageServersRegistry.getInstance()
|
||||
.getDefinition("org.eclipse.languageserver.languages.springboot"));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Pivotal Software, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal Software, 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
|
||||
@@ -20,7 +20,6 @@ import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
|
||||
import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveProcessCommandsExecutor.Server;
|
||||
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
|
||||
import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ElementStateListener;
|
||||
import org.springframework.ide.eclipse.boot.dash.model.RunState;
|
||||
@@ -35,8 +34,6 @@ import org.springsource.ide.eclipse.commons.livexp.util.Log;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class LiveDataConnectionManagementActions extends AbstractDisposable implements DynamicSubMenuSupplier {
|
||||
|
||||
private static final IAction DUMMY_ACTION = new Action("No matching processes") {
|
||||
@@ -75,12 +72,10 @@ public class LiveDataConnectionManagementActions extends AbstractDisposable impl
|
||||
public class ExecuteCommandAction extends AbstractBootDashElementsAction {
|
||||
private String projectName;
|
||||
private String label;
|
||||
private Server server;
|
||||
private CommandInfo commandInfo;
|
||||
|
||||
public ExecuteCommandAction(Server server, CommandInfo commandInfo) {
|
||||
public ExecuteCommandAction(CommandInfo commandInfo) {
|
||||
super(params);
|
||||
this.server = server;
|
||||
this.commandInfo = commandInfo;
|
||||
String command = commandInfo.command;
|
||||
int lastSlash = command.lastIndexOf("/");
|
||||
@@ -113,7 +108,7 @@ public class LiveDataConnectionManagementActions extends AbstractDisposable impl
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
server.executeCommand(commandInfo).block(Duration.ofSeconds(2));
|
||||
liveProcessCmds.executeCommand(commandInfo).block(Duration.ofSeconds(2));
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
@@ -128,7 +123,7 @@ public class LiveDataConnectionManagementActions extends AbstractDisposable impl
|
||||
this.params = params;
|
||||
this.liveProcessCmds = params.getLiveProcessCmds();
|
||||
ObservableSet<BootDashElement> selection = params.getSelection().getElements();
|
||||
this.isEnabled = addDisposableChild(new LiveExpression<Boolean>(false) {
|
||||
this.isEnabled = addDisposableChild(new LiveExpression<>(false) {
|
||||
|
||||
ElementStateListener elementStateListener = (BootDashElement e) -> {
|
||||
refresh();
|
||||
@@ -178,12 +173,7 @@ public class LiveDataConnectionManagementActions extends AbstractDisposable impl
|
||||
};
|
||||
}
|
||||
try {
|
||||
List<LiveProcessCommandsExecutor.Server> servers = liveProcessCmds.getLanguageServers();
|
||||
return Flux.fromIterable(servers)
|
||||
.flatMap((Server server) ->
|
||||
server.listCommands()
|
||||
.map(cmdInfo -> new ExecuteCommandAction(server, cmdInfo))
|
||||
)
|
||||
return liveProcessCmds.listCommands().map(cmdInfo -> new ExecuteCommandAction(cmdInfo))
|
||||
.filter(filter)
|
||||
.cast(IAction.class)
|
||||
.collect(Collectors.toList())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Pivotal Software, Inc.
|
||||
* Copyright (c) 2019, 2023 Pivotal Software, 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
|
||||
@@ -10,21 +10,15 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.eclipse.boot.dash.liveprocess;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface LiveProcessCommandsExecutor {
|
||||
|
||||
interface Server {
|
||||
Flux<CommandInfo> listCommands();
|
||||
Mono<Void> executeCommand(CommandInfo cmd);
|
||||
}
|
||||
Flux<CommandInfo> listCommands();
|
||||
Mono<Void> executeCommand(CommandInfo cmd);
|
||||
|
||||
static LiveProcessCommandsExecutor getDefault() {
|
||||
return new DefaultLiveProcessCommandExecutor();
|
||||
}
|
||||
|
||||
List<Server> getLanguageServers();
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@ import org.springframework.tooling.boot.ls.prefs.LiveInformationPreferencePage;
|
||||
*/
|
||||
public class BootLanguageServerPlugin extends AbstractUIPlugin {
|
||||
|
||||
public static String BOOT_LS_DEFINITION_ID = "org.eclipse.languageserver.languages.springboot";
|
||||
|
||||
public static String PLUGIN_ID = "org.springframework.tooling.boot.ls";
|
||||
|
||||
private static final Object LSP4E_COMMAND_SYMBOL_IN_WORKSPACE = "org.eclipse.lsp4e.symbolinworkspace";
|
||||
@@ -41,6 +39,8 @@ public class BootLanguageServerPlugin extends AbstractUIPlugin {
|
||||
// The shared instance
|
||||
private static BootLanguageServerPlugin plugin;
|
||||
|
||||
public static final String BOOT_LS_DEFINITION_ID = "org.eclipse.languageserver.languages.springboot";
|
||||
|
||||
public BootLanguageServerPlugin() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.springframework.tooling.jdt.ls.commons.Logger;
|
||||
@SuppressWarnings("restriction")
|
||||
public class Startup implements IStartup {
|
||||
|
||||
private static final String BOOT_LS_DEFINITION_ID = "org.eclipse.languageserver.languages.springboot";
|
||||
private boolean started;
|
||||
|
||||
@Override
|
||||
@@ -41,7 +40,7 @@ public class Startup implements IStartup {
|
||||
if (!started && !springProjects.isEmpty()) {
|
||||
BootLanguageServerPlugin.getDefault().getLog().info("Starting Boot LS...");
|
||||
LanguageServerDefinition serverDefinition = LanguageServersRegistry.getInstance()
|
||||
.getDefinition(BOOT_LS_DEFINITION_ID);
|
||||
.getDefinition(BootLanguageServerPlugin.BOOT_LS_DEFINITION_ID);
|
||||
|
||||
try {
|
||||
LanguageServiceAccessor.startLanguageServer(serverDefinition);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2023 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
|
||||
@@ -18,12 +18,12 @@ import java.util.Random;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServers;
|
||||
import org.eclipse.lsp4e.LanguageServersRegistry;
|
||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.quickaccess.QuickAccessElement;
|
||||
import org.springframework.tooling.boot.ls.BootLanguageServerPlugin;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -79,12 +79,6 @@ public class LiveProcessCommandElement extends QuickAccessElement {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<@NonNull LanguageServer> usedLanguageServers = LanguageServiceAccessor.getActiveLanguageServers(serverCapabilities -> true);
|
||||
|
||||
if (usedLanguageServers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExecuteCommandParams commandParams = new ExecuteCommandParams();
|
||||
commandParams.setCommand(this.action);
|
||||
|
||||
@@ -94,10 +88,15 @@ public class LiveProcessCommandElement extends QuickAccessElement {
|
||||
arguments.add(argumentMap);
|
||||
|
||||
commandParams.setArguments(arguments);
|
||||
|
||||
List<CompletableFuture<Object>> futures = LanguageServers
|
||||
.forProject(null)
|
||||
.excludeInactive()
|
||||
.withPreferredServer(LanguageServersRegistry.getInstance().getDefinition(BootLanguageServerPlugin.BOOT_LS_DEFINITION_ID))
|
||||
.computeAll(ls -> ls.getWorkspaceService().executeCommand(commandParams));
|
||||
|
||||
try {
|
||||
CompletableFuture.allOf(usedLanguageServers.stream().map(ls ->
|
||||
ls.getWorkspaceService().executeCommand(commandParams)).toArray(CompletableFuture[]::new)).get(2, TimeUnit.SECONDS);
|
||||
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).get(2, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// TODO: better exception handling
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2023 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
|
||||
@@ -19,12 +19,15 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.lsp4e.LanguageServers;
|
||||
import org.eclipse.lsp4e.LanguageServersRegistry;
|
||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.quickaccess.IQuickAccessComputer;
|
||||
import org.eclipse.ui.quickaccess.IQuickAccessComputerExtension;
|
||||
import org.eclipse.ui.quickaccess.QuickAccessElement;
|
||||
import org.springframework.tooling.boot.ls.BootLanguageServerPlugin;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -50,23 +53,24 @@ public class LiveProcessCommandsQuickAccessProvider implements IQuickAccessCompu
|
||||
|
||||
@Override
|
||||
public QuickAccessElement[] computeElements(String query, IProgressMonitor monitor) {
|
||||
this.usedLanguageServers = LanguageServiceAccessor.getActiveLanguageServers(serverCapabilities -> true);
|
||||
|
||||
if (usedLanguageServers.isEmpty()) {
|
||||
return new QuickAccessElement[0];
|
||||
}
|
||||
|
||||
ExecuteCommandParams commandParams = new ExecuteCommandParams();
|
||||
commandParams.setCommand(LiveProcessCommandElement.COMMAND_LIST_PROCESSES);
|
||||
|
||||
List<QuickAccessElement> res = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
usedLanguageServers = new ArrayList<>();
|
||||
@NonNull
|
||||
List<@NonNull CompletableFuture<@Nullable Void>> futures = LanguageServers
|
||||
.forProject(null)
|
||||
.excludeInactive()
|
||||
.withPreferredServer(LanguageServersRegistry.getInstance().getDefinition(BootLanguageServerPlugin.BOOT_LS_DEFINITION_ID))
|
||||
.computeAll(ls -> {
|
||||
usedLanguageServers.add(ls);
|
||||
return ls.getWorkspaceService().executeCommand(commandParams).thenAcceptAsync(commandResult ->
|
||||
createCommandItems(res, commandResult));
|
||||
});
|
||||
try {
|
||||
CompletableFuture.allOf(usedLanguageServers.stream().map(ls ->
|
||||
ls.getWorkspaceService().executeCommand(commandParams).thenAcceptAsync(commandResult ->
|
||||
createCommandItems(res, commandResult))).toArray(CompletableFuture[]::new)).get(2000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (Exception e) {
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).get(2000, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
// TODO: better error handling
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServers;
|
||||
import org.eclipse.lsp4e.LanguageServersRegistry;
|
||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.quickaccess.IQuickAccessComputer;
|
||||
import org.eclipse.ui.quickaccess.IQuickAccessComputerExtension;
|
||||
import org.eclipse.ui.quickaccess.QuickAccessElement;
|
||||
@@ -60,20 +60,19 @@ public class SpringQuickAccessProvider implements IQuickAccessComputer, IQuickAc
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<LanguageServer> usedLanguageServers = LanguageServiceAccessor.getActiveLanguageServers(serverCapabilities -> true);
|
||||
|
||||
if (usedLanguageServers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExecuteCommandParams commandParams = new ExecuteCommandParams();
|
||||
commandParams.setCommand(commandId);
|
||||
|
||||
commandParams.setArguments(Collections.emptyList());
|
||||
|
||||
List<CompletableFuture<Object>> futures = LanguageServers
|
||||
.forProject(null)
|
||||
.excludeInactive()
|
||||
.withPreferredServer(LanguageServersRegistry.getInstance().getDefinition(BootLanguageServerPlugin.BOOT_LS_DEFINITION_ID))
|
||||
.computeAll(ls -> ls.getWorkspaceService().executeCommand(commandParams));
|
||||
|
||||
try {
|
||||
CompletableFuture.allOf(usedLanguageServers.stream().map(ls ->
|
||||
ls.getWorkspaceService().executeCommand(commandParams)).toArray(CompletableFuture[]::new)).get(2, TimeUnit.SECONDS);
|
||||
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).get(2, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (Exception e) {
|
||||
BootLanguageServerPlugin.getDefault().getLog().error(errorMsg, e);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2023 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
|
||||
@@ -11,15 +11,14 @@
|
||||
package org.springframework.tooling.ls.eclipse.commons;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServers;
|
||||
import org.eclipse.lsp4j.ExecuteCommandOptions;
|
||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||
import org.eclipse.lsp4j.ServerCapabilities;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.springframework.tooling.jdt.ls.commons.classpath.ClientCommandExecutor;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@@ -27,19 +26,11 @@ public class LSP4ECommandExecutor implements ClientCommandExecutor {
|
||||
|
||||
@Override
|
||||
public Object executeClientCommand(String id, Object... params) throws Exception {
|
||||
List<LanguageServer> commandHandlers = LanguageServiceAccessor.getActiveLanguageServers(handlesCommand(id));
|
||||
if (commandHandlers != null) {
|
||||
if (commandHandlers.size() == 1) {
|
||||
LanguageServer handler = commandHandlers.get(0);
|
||||
return handler
|
||||
.getWorkspaceService()
|
||||
.executeCommand(new ExecuteCommandParams(id, Arrays.asList(params)))
|
||||
.get(2, TimeUnit.SECONDS);
|
||||
} else if (commandHandlers.size() > 1) {
|
||||
throw new IllegalStateException("Multiple language servers have registered to handle command '"+id+"'");
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("No language server has registered to handle command '"+id+"'");
|
||||
Optional<Object> res = LanguageServers.forProject(null).withFilter(handlesCommand(id)).computeFirst(
|
||||
ls -> ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(id, Arrays.asList(params))))
|
||||
.get(2, TimeUnit.SECONDS);
|
||||
return res.orElseThrow(() -> new UnsupportedOperationException(
|
||||
"No language server has registered to handle command '" + id + "'"));
|
||||
}
|
||||
|
||||
private Predicate<ServerCapabilities> handlesCommand(String id) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
@@ -18,13 +19,13 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.lsp4e.LSPEclipseUtils;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServers;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.BeansParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexLanguageServer;
|
||||
@@ -41,16 +42,7 @@ import reactor.core.publisher.Mono;
|
||||
public class InProjectSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
public static InProjectSymbolsProvider createFor(LiveExpression<IProject> project) {
|
||||
LiveExpression<List<LanguageServer>> languageServers = project.apply(p -> {
|
||||
return p == null
|
||||
? ImmutableList.of()
|
||||
: LanguageServiceAccessor.getLanguageServers(
|
||||
project.getValue(),
|
||||
capabilities -> LSPEclipseUtils.hasCapability(capabilities.getWorkspaceSymbolProvider()),
|
||||
true
|
||||
);
|
||||
});
|
||||
return new InProjectSymbolsProvider(languageServers::getValue, project::getValue);
|
||||
return new InProjectSymbolsProvider(project::getValue);
|
||||
}
|
||||
|
||||
public static InProjectSymbolsProvider createFor(ExecutionEvent event) {
|
||||
@@ -64,11 +56,9 @@ public class InProjectSymbolsProvider implements SymbolsProvider {
|
||||
private static final Duration TIMEOUT = Duration.ofSeconds(2);
|
||||
private static final int MAX_RESULTS = 200;
|
||||
|
||||
private Supplier<List<LanguageServer>> languageServers;
|
||||
private Supplier<IProject> project;
|
||||
|
||||
public InProjectSymbolsProvider(Supplier<List<LanguageServer>> languageServers, Supplier<IProject> project) {
|
||||
this.languageServers = languageServers;
|
||||
public InProjectSymbolsProvider(Supplier<IProject> project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@@ -99,10 +89,15 @@ public class InProjectSymbolsProvider implements SymbolsProvider {
|
||||
|
||||
WorkspaceSymbolParams params = new WorkspaceSymbolParams(query);
|
||||
|
||||
List<LanguageServer> servers = this.languageServers.get();
|
||||
List<CompletableFuture<Either<List<? extends SymbolInformation>, List<? extends WorkspaceSymbol>>>> responses = LanguageServers
|
||||
.forProject(project)
|
||||
.withFilter(capabilities -> LSPEclipseUtils.hasCapability(capabilities.getWorkspaceSymbolProvider()))
|
||||
.excludeInactive()
|
||||
.computeAll(ls -> ls.getWorkspaceService().symbol(params));
|
||||
|
||||
|
||||
Flux<Either<List<? extends SymbolInformation>, List<? extends WorkspaceSymbol>>> first = Flux.fromIterable(servers)
|
||||
.flatMap(server -> Mono.fromFuture(server.getWorkspaceService().symbol(params)))
|
||||
Flux<Either<List<? extends SymbolInformation>, List<? extends WorkspaceSymbol>>> first = Flux.fromIterable(responses)
|
||||
.flatMap(Mono::fromFuture)
|
||||
.timeout(TIMEOUT);
|
||||
|
||||
Flux<SymbolContainer> symbols = first
|
||||
@@ -128,31 +123,34 @@ public class InProjectSymbolsProvider implements SymbolsProvider {
|
||||
GotoSymbolPlugin.getInstance().getLog().log(ExceptionUtil.status(e));
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private void dumpBeansModel(String projectName) {
|
||||
List<LanguageServer> activeLanguageServers = LanguageServiceAccessor.getActiveLanguageServers(null);
|
||||
IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
|
||||
|
||||
for (LanguageServer languageServer : activeLanguageServers) {
|
||||
if (languageServer instanceof SpringIndexLanguageServer) {
|
||||
SpringIndexLanguageServer springServer = (SpringIndexLanguageServer) languageServer;
|
||||
BeansParams beansParams = new BeansParams();
|
||||
beansParams.setProjectName(projectName);
|
||||
|
||||
BeansParams beansParams = new BeansParams();
|
||||
beansParams.setProjectName(projectName);
|
||||
|
||||
CompletableFuture<List<Bean>> beansFuture = springServer.beans(beansParams);
|
||||
|
||||
try {
|
||||
List<Bean> beans = beansFuture.get();
|
||||
|
||||
for (Bean bean : beans) {
|
||||
System.out.println(bean);
|
||||
List<CompletableFuture<List<Bean>>> executors = LanguageServers
|
||||
.forProject(p)
|
||||
.withFilter(capabilities -> LSPEclipseUtils.hasCapability(capabilities.getWorkspaceSymbolProvider()))
|
||||
.excludeInactive()
|
||||
.computeAll(ls -> {
|
||||
if (ls instanceof SpringIndexLanguageServer) {
|
||||
return ((SpringIndexLanguageServer) ls).beans(beansParams);
|
||||
}
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
});
|
||||
|
||||
for (CompletableFuture<List<Bean>> beansFuture : executors) {
|
||||
try {
|
||||
List<Bean> beans = beansFuture.get();
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (java.util.concurrent.ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
for (Bean bean : beans) {
|
||||
System.out.println(bean);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (java.util.concurrent.ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -22,13 +23,13 @@ import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.lsp4e.LSPEclipseUtils;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.LanguageServers;
|
||||
import org.eclipse.lsp4e.LanguageServers.LanguageServerProjectExecutor;
|
||||
import org.eclipse.lsp4j.ServerCapabilities;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.handlers.HandlerUtil;
|
||||
import org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin;
|
||||
@@ -45,32 +46,21 @@ public class InWorkspaceSymbolsProvider implements SymbolsProvider {
|
||||
private static final Predicate<ServerCapabilities> WS_SYMBOL_CAP = capabilities -> LSPEclipseUtils.hasCapability(capabilities.getWorkspaceSymbolProvider());
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(Supplier<IProject> _project) {
|
||||
return new InWorkspaceSymbolsProvider(() -> {
|
||||
IProject project = _project.get();
|
||||
if (project!=null) {
|
||||
return LanguageServiceAccessor.getLanguageServers(project,
|
||||
WS_SYMBOL_CAP, true);
|
||||
} else {
|
||||
return LanguageServiceAccessor.getActiveLanguageServers(WS_SYMBOL_CAP);
|
||||
}
|
||||
});
|
||||
LanguageServerProjectExecutor lss = LanguageServers.forProject(_project.get()).withFilter(WS_SYMBOL_CAP).excludeInactive();
|
||||
return new InWorkspaceSymbolsProvider(lss);
|
||||
}
|
||||
|
||||
public static InWorkspaceSymbolsProvider createFor(IProject project) {
|
||||
List<LanguageServer> languageServers = LanguageServiceAccessor.getLanguageServers(project,
|
||||
capabilities -> LSPEclipseUtils.hasCapability(capabilities.getWorkspaceSymbolProvider()), true);
|
||||
if (!languageServers.isEmpty()) {
|
||||
return new InWorkspaceSymbolsProvider(() -> languageServers);
|
||||
}
|
||||
return null;
|
||||
LanguageServerProjectExecutor lss = LanguageServers.forProject(project).withFilter(capabilities -> LSPEclipseUtils.hasCapability(capabilities.getWorkspaceSymbolProvider())).excludeInactive();
|
||||
return new InWorkspaceSymbolsProvider(lss);
|
||||
}
|
||||
|
||||
|
||||
private static final Duration TIMEOUT = Duration.ofSeconds(2);
|
||||
private static final int MAX_RESULTS = 200;
|
||||
private Supplier<List<LanguageServer>> languageServers;
|
||||
private LanguageServers<?> languageServers;
|
||||
|
||||
public InWorkspaceSymbolsProvider(Supplier<List<LanguageServer>> languageServers) {
|
||||
public InWorkspaceSymbolsProvider(LanguageServers<?> languageServers) {
|
||||
this.languageServers = languageServers;
|
||||
}
|
||||
|
||||
@@ -91,12 +81,10 @@ public class InWorkspaceSymbolsProvider implements SymbolsProvider {
|
||||
//However it will also add complexity to the code that consumes this and at this time we only
|
||||
// really use this with a single language server anyways.
|
||||
WorkspaceSymbolParams params = new WorkspaceSymbolParams(query);
|
||||
|
||||
List<LanguageServer> servers = this.languageServers.get();
|
||||
|
||||
Flux<Either<List<? extends SymbolInformation>, List<? extends WorkspaceSymbol>>> first = Flux.fromIterable(servers)
|
||||
.flatMap(server -> Mono.fromFuture(server.getWorkspaceService().symbol(params)))
|
||||
.timeout(TIMEOUT);
|
||||
List<CompletableFuture<Either<List<? extends SymbolInformation>, List<? extends WorkspaceSymbol>>>> responses = languageServers.computeAll(ls -> ls.getWorkspaceService().symbol(params));
|
||||
|
||||
Flux<Either<List<? extends SymbolInformation>, List<? extends WorkspaceSymbol>>> first = Flux.fromIterable(responses).flatMap(Mono::fromFuture).timeout(TIMEOUT);
|
||||
|
||||
Flux<SymbolContainer> symbols = first
|
||||
.doOnError(e -> log(e))
|
||||
|
||||
Reference in New Issue
Block a user