diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/CompositeLanguageServerComponents.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/CompositeLanguageServerComponents.java index 2bef2ce4a..154416868 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/CompositeLanguageServerComponents.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/CompositeLanguageServerComponents.java @@ -71,9 +71,9 @@ public class CompositeLanguageServerComponents implements LanguageServerComponen //Create composite Completion engine this.completionEngine = new CompositeCompletionEngine(); for (Entry entry : componentsByLanguageId.entrySet()) { - ICompletionEngine engine = entry.getValue().getCompletionEngine(); + ICompletionEngine engine = entry.getValue().getCompletionEngine().orElse(null); if (engine!=null) { - completionEngine.add(entry.getKey(), entry.getValue().getCompletionEngine()); + completionEngine.add(entry.getKey(), engine); } } if (builder.completionEngines!=null) { @@ -127,8 +127,8 @@ public class CompositeLanguageServerComponents implements LanguageServerComponen } @Override - public ICompletionEngine getCompletionEngine() { - return completionEngine; + public Optional getCompletionEngine() { + return Optional.ofNullable(completionEngine); } @Override diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java index 9bda07f16..1c9c0d1a2 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java @@ -16,12 +16,21 @@ import java.util.Set; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine; import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler; +import org.springframework.ide.vscode.commons.languageserver.util.LanguageSpecific; import org.springframework.ide.vscode.commons.util.text.LanguageId; public interface LanguageServerComponents { Set getInterestingLanguages(); default Optional getReconcileEngine() { return Optional.empty(); } - ICompletionEngine getCompletionEngine(); + + /** + * Don't use language server components. Instead create a bean of type ICompletionEngine that implements + * {@link LanguageSpecific}. The bean will be automatically wired up to handle completion requests for + * documents of the language(s) it handles. + */ + @Deprecated + default Optional getCompletionEngine() { return Optional.empty(); } + HoverHandler getHoverProvider(); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java index 3682f4f5c..53cf67e9c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java @@ -15,6 +15,8 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; @@ -44,8 +46,10 @@ import org.springframework.ide.vscode.boot.metadata.LoggerNameProvider; import org.springframework.ide.vscode.boot.metadata.ProjectBasedPropertyIndexProvider; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndex; import org.springframework.ide.vscode.boot.metadata.ValueProviderRegistry; +import org.springframework.ide.vscode.boot.xml.SpringXMLCompletionEngine; import org.springframework.ide.vscode.boot.yaml.completions.ApplicationYamlAssistContext; import org.springframework.ide.vscode.commons.languageserver.LanguageServerRunner; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.util.DocumentEventListenerManager; import org.springframework.ide.vscode.commons.languageserver.util.LspClient; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; @@ -73,8 +77,9 @@ import reactor.core.publisher.Hooks; ConfigurationPropertiesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) -@EnableConfigurationProperties(BootLsConfigProperties.class) @ComponentScan +@EnableConfigurationProperties(BootLsConfigProperties.class) +//@SpringBootApplication public class BootLanguagServerBootApp { private static final String SERVER_NAME = "boot-language-server"; @@ -141,6 +146,10 @@ public class BootLanguagServerBootApp { return new CompilationUnitCache(params.projectFinder, server, params.projectObserver); } + @Bean SpringXMLCompletionEngine xmlCompletionEngine(SimpleLanguageServer server, JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex, BootJavaConfig config) { + return new SpringXMLCompletionEngine(server, projectFinder, symbolIndex, config); + } + @Bean JavaDocumentUriProvider javaDocumentUriProvider() { switch (LspClient.currentClient()) { case ECLIPSE: diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java index b3e054801..2e88c6f48 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerInitializer.java @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.boot.app; import java.util.List; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -99,7 +100,7 @@ public class BootLanguageServerInitializer implements InitializingBean { }); }); - ICompletionEngine completionEngine = components.getCompletionEngine(); + ICompletionEngine completionEngine = components.getCompletionEngine().orElse(null); if (completionEngine!=null) { completionEngineAdapter = server.createCompletionEngineAdapter(completionEngine); completionEngineAdapter.setMaxCompletions(100); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java index 0ecc4a4f6..2477a31e9 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java @@ -239,8 +239,8 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent } @Override - public ICompletionEngine getCompletionEngine() { - return createCompletionEngine(projectFinder, propertyIndexProvider, adHocPropertyIndexProvider); + public Optional getCompletionEngine() { + return Optional.of(createCompletionEngine(projectFinder, propertyIndexProvider, adHocPropertyIndexProvider)); } @Override diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java index 791b7003e..9b8a38d04 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java @@ -127,10 +127,10 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom } @Override - public ICompletionEngine getCompletionEngine() { + public Optional getCompletionEngine() { ICompletionEngine propertiesCompletions = new SpringPropertiesCompletionEngine(indexProvider, typeUtilProvider, javaProjectFinder, sourceLinks); ICompletionEngine yamlCompletions = new YamlCompletionEngine(yamlStructureProvider, yamlAssistContextProvider, COMPLETION_OPTIONS); - return (TextDocument document, int offset) -> { + return Optional.of((TextDocument document, int offset) -> { String uri = document.getUri(); if (uri!=null) { if (uri.endsWith(PROPERTIES)) { @@ -144,7 +144,7 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom } } return ImmutableList.of(); - }; + }); } @Override diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java index 5327588c8..517996012 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLCompletionEngine.java @@ -63,22 +63,30 @@ import org.springframework.ide.vscode.boot.xml.completions.TypeCompletionProposa import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.util.LanguageSpecific; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; +import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.commons.util.text.TextDocument; +import com.google.common.collect.ImmutableList; + /** * @author Martin Lippert + * @author Kris De Volder */ -public class SpringXMLCompletionEngine implements ICompletionEngine { +public class SpringXMLCompletionEngine implements ICompletionEngine, LanguageSpecific { private final Map completionProviders; private final BootJavaConfig config; - public SpringXMLCompletionEngine(SpringXMLLanguageServerComponents springXMLLanguageServerComponents, - SimpleLanguageServer server, JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex, BootJavaConfig config) { + public SpringXMLCompletionEngine( + SimpleLanguageServer server, + JavaProjectFinder projectFinder, + SpringSymbolIndex symbolIndex, + BootJavaConfig config + ) { this.config = config; - this.completionProviders = new HashMap<>(); TypeCompletionProposalProvider classesOnlyProvider = new TypeCompletionProposalProvider(server, projectFinder, true, true, false, false); @@ -166,4 +174,8 @@ public class SpringXMLCompletionEngine implements ICompletionEngine { return Collections.emptyList(); } + @Override + public Collection supportedLanguages() { + return ImmutableList.of(LanguageId.XML); + } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java index d31a6a9b7..db1bd6c96 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/xml/SpringXMLLanguageServerComponents.java @@ -13,12 +13,9 @@ package org.springframework.ide.vscode.boot.xml; import java.util.Optional; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.app.BootJavaConfig; import org.springframework.ide.vscode.boot.app.BootLanguageServerParams; import org.springframework.ide.vscode.boot.app.SpringSymbolIndex; -import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; import org.springframework.ide.vscode.commons.languageserver.composable.LanguageServerComponents; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine; @@ -35,31 +32,20 @@ public class SpringXMLLanguageServerComponents implements LanguageServerComponen public static final Set LANGUAGES = ImmutableSet.of(LanguageId.XML); - private static final Logger log = LoggerFactory.getLogger(SpringXMLLanguageServerComponents.class); - - private final SimpleLanguageServer server; - private final BootLanguageServerParams serverParams; private final JavaProjectFinder projectFinder; - private final SpringSymbolIndex symbolIndex; - private final SpringXMLCompletionEngine completionEngine; private final SpringXMLReconcileEngine reconcileEngine; - public SpringXMLLanguageServerComponents( SimpleLanguageServer server, SpringSymbolIndex springIndexer, BootLanguageServerParams serverParams, BootJavaConfig config) { - this.server = server; - this.serverParams = serverParams; this.projectFinder = serverParams.projectFinder; - this.symbolIndex = springIndexer; server.doOnInitialized(this::initialized); server.onShutdown(this::shutdown); - this.completionEngine = new SpringXMLCompletionEngine(this, server, projectFinder, symbolIndex, config); this.reconcileEngine = new SpringXMLReconcileEngine(projectFinder); config.addListener(ignore -> { @@ -73,11 +59,6 @@ public class SpringXMLLanguageServerComponents implements LanguageServerComponen return LANGUAGES; } - @Override - public ICompletionEngine getCompletionEngine() { - return this.completionEngine; - } - @Override public Optional getReconcileEngine() { return Optional.of(this.reconcileEngine);