Adopt API removal in LSP4E

This commit is contained in:
aboyko
2023-06-05 19:03:29 -04:00
parent b59b6123dd
commit 7a6603f520
12 changed files with 143 additions and 186 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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