diff --git a/build.gradle b/build.gradle index bf31925b5..e5f8ef12f 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,7 @@ dependencies { // Test: Video Recording. testImplementation 'com.automation-remarks:video-recorder-junit5:2.0' + // define jars to grab locally (if falling back to mavenLocal() repo) lsp('org.eclipse.lsp4mp:org.eclipse.lsp4mp.ls:0.6.0:uber') { transitive = false } diff --git a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyConfigLanguageClient.java b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyConfigLanguageClient.java index fa4c1813c..12c3056e8 100644 --- a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyConfigLanguageClient.java +++ b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyConfigLanguageClient.java @@ -10,37 +10,46 @@ ******************************************************************************/ package io.openliberty.tools.intellij.liberty.lsp; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.vfs.VirtualFile; -import io.openliberty.tools.intellij.lsp4mp.MicroProfileProjectService; -import io.openliberty.tools.intellij.lsp4mp.lsp4ij.LanguageClientImpl; -import org.apache.commons.lang3.tuple.Pair; +import java.util.List; + +import org.eclipse.lsp4j.DidChangeWatchedFilesParams; +import org.eclipse.lsp4j.FileChangeType; +import org.eclipse.lsp4j.FileEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; +import com.intellij.openapi.project.Project; +import com.intellij.util.messages.MessageBusConnection; + +import io.openliberty.tools.intellij.lsp4mp.lsp4ij.LanguageClientImpl; +import io.openliberty.tools.intellij.lsp4mp.lsp4ij.LanguageServerWrapper; /** * Client for Liberty language server * Adapted from https://github.com/redhat-developer/intellij-quarkus/blob/2585eb422beeb69631076d2c39196d6eca2f5f2e/src/main/java/com/redhat/devtools/intellij/quarkus/lsp/QuarkusLanguageClient.java */ -public class LibertyConfigLanguageClient extends LanguageClientImpl implements MicroProfileProjectService.Listener { +public class LibertyConfigLanguageClient extends LanguageClientImpl implements LibertyCustomConfigManager.Listener { private static final Logger LOGGER = LoggerFactory.getLogger(LibertyConfigLanguageClient.class); + private final MessageBusConnection connection; + public LibertyConfigLanguageClient(Project project) { super(project); + connection = project.getMessageBus().connect(project); + connection.subscribe(LibertyCustomConfigManager.TOPIC, this); + LibertyCustomConfigManager.getInstance(project); } @Override - public void libraryUpdated(Library library) { - // not needed for Liberty LS - } - - @Override - public void sourceUpdated(List> sources) { - // not needed for Liberty LS + public void processConfigXml(List uris) { + LanguageServerWrapper wrapper = getLanguageServerWrapper(); + if (wrapper != null) { + List fileEvents = uris.stream() + .map(uri -> new FileEvent(uri, FileChangeType.Changed)).toList(); + DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(); + params.setChanges(fileEvents); + wrapper.getInitializedServer().thenAccept(ls -> ls.getWorkspaceService().didChangeWatchedFiles(params)); + } } } diff --git a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyCustomConfigListener.java b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyCustomConfigListener.java new file mode 100644 index 000000000..794f15f85 --- /dev/null +++ b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyCustomConfigListener.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2023 IBM Corporation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ******************************************************************************/ +package io.openliberty.tools.intellij.liberty.lsp; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vfs.newvfs.BulkFileListener; +import com.intellij.openapi.vfs.newvfs.events.VFileEvent; +import io.openliberty.tools.intellij.lsp4mp.lsp4ij.LSPIJUtils; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class LibertyCustomConfigListener implements BulkFileListener { + private final static Logger LOGGER = Logger.getInstance(LibertyCustomConfigListener.class); + + private final LibertyCustomConfigManager manager; + public static final String LIBERTY_PLUGIN_CONFIG_XML = "liberty-plugin-config.xml"; + + public LibertyCustomConfigListener(LibertyCustomConfigManager manager) { + this.manager = manager; + } + + @Override + public void after(@NotNull List events) { + // filter file events to only liberty-plugin-config.xml + List pluginConfigList = events.stream() + .map(event -> LSPIJUtils.toUri(event.getFile()).toString()) + .filter(this::isPluginConfigXml) + .toList(); + manager.handleProcessConfigXml(pluginConfigList); + } + + private boolean isPluginConfigXml(String uri) { + return uri.endsWith(LIBERTY_PLUGIN_CONFIG_XML); + } +} diff --git a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyCustomConfigManager.java b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyCustomConfigManager.java new file mode 100644 index 000000000..a9de78809 --- /dev/null +++ b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/LibertyCustomConfigManager.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2023 IBM Corporation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ******************************************************************************/ +package io.openliberty.tools.intellij.liberty.lsp; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.util.messages.MessageBusConnection; +import com.intellij.util.messages.Topic; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class LibertyCustomConfigManager implements LibraryTable.Listener, Disposable { + + private final static Logger LOGGER = Logger.getInstance(LibertyCustomConfigManager.class); + + private final Project project; + private final MessageBusConnection appConnection; + private final LibertyCustomConfigListener listener; + + @Override + public void dispose() { + this.appConnection.disconnect(); + } + + public interface Listener { + void processConfigXml(List uris); + } + + public static LibertyCustomConfigManager getInstance(@NotNull Project project) { + return project.getService(LibertyCustomConfigManager.class); + } + + public static final Topic TOPIC = Topic.create(LibertyCustomConfigManager.class.getName(), Listener.class); + + + public LibertyCustomConfigManager(Project project) { + this.project = project; + listener = new LibertyCustomConfigListener(this); + appConnection = ApplicationManager.getApplication().getMessageBus().connect(project); + appConnection.subscribe(VirtualFileManager.VFS_CHANGES, listener); + } + + protected void handleProcessConfigXml(List uris) { + project.getMessageBus().syncPublisher(TOPIC).processConfigXml(uris); + } +} diff --git a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvFileType.java b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvFileType.java index d4cbdffdc..385e29d43 100644 --- a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvFileType.java +++ b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvFileType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 IBM Corporation. + * Copyright (c) 2022, 2023 IBM Corporation. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -9,11 +9,6 @@ *******************************************************************************/ package io.openliberty.tools.intellij.liberty.lsp; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.PathMatcher; -import java.nio.file.Paths; - import javax.swing.Icon; import com.intellij.openapi.fileTypes.PlainTextLanguage; @@ -27,8 +22,6 @@ import io.openliberty.tools.intellij.LibertyPluginIcons; -import static io.openliberty.tools.intellij.util.Constants.SERVER_ENV_GLOB_PATTERN; - /** * Custom file type for server.env files */ @@ -43,9 +36,7 @@ private ServerEnvFileType() { @Override public boolean isMyFileType(@NotNull VirtualFile file) { - Path path = Paths.get(file.getPath()); - final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + SERVER_ENV_GLOB_PATTERN); - return matcher.matches(path); + return file.getPath().endsWith(".env"); } @Override diff --git a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvSubstitutor.java b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvSubstitutor.java index ba3751455..f1ff61760 100644 --- a/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvSubstitutor.java +++ b/src/main/java/io/openliberty/tools/intellij/liberty/lsp/ServerEnvSubstitutor.java @@ -21,13 +21,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.PathMatcher; -import java.nio.file.Paths; - -import static io.openliberty.tools.intellij.util.Constants.SERVER_ENV_GLOB_PATTERN; - /** * Language Substitutor for Liberty server.env files * To re-use the IntelliJ parsing for Properties files on server.env files, categorize server.env files that are in a recognized @@ -47,8 +40,6 @@ public class ServerEnvSubstitutor extends LanguageSubstitutor { } private boolean isLibertyServerEnvFile(VirtualFile file) { - Path path = Paths.get(file.getPath()); - final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + SERVER_ENV_GLOB_PATTERN); - return matcher.matches(path); + return file.getPath().endsWith(".env"); } } diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageClientImpl.java b/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageClientImpl.java index 1c4c4fff5..20ddbf9af 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageClientImpl.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageClientImpl.java @@ -49,6 +49,9 @@ public final void connect(LanguageServer server, LanguageServerWrapper wrapper) protected final LanguageServer getLanguageServer() { return server; } + protected final LanguageServerWrapper getLanguageServerWrapper() { + return wrapper; + } @Override public void telemetryEvent(Object object) { diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageServerWrapper.java b/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageServerWrapper.java index dbad11006..ccabc44ff 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageServerWrapper.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4mp/lsp4ij/LanguageServerWrapper.java @@ -363,10 +363,10 @@ private void logMessage(Message message) { ResponseMessage responseMessage = (ResponseMessage) message; LOGGER.warn("", new ResponseErrorException(responseMessage.getError())); } else if (LOGGER.isDebugEnabled()) { - LOGGER.info(message.getClass().getSimpleName() + '\n' + message.toString()); + LOGGER.warn(message.getClass().getSimpleName() + ": " + this.serverDefinition.id + '\n' + message.toString()); } // else { -// LOGGER.warn(message.getClass().getSimpleName() + '\n' + message.toString()); +// LOGGER.warn(message.getClass().getSimpleName() + ": " + this.serverDefinition.id + '\n' + message.toString()); // } } diff --git a/src/main/java/io/openliberty/tools/intellij/util/Constants.java b/src/main/java/io/openliberty/tools/intellij/util/Constants.java index 9f1ab01b3..b5f2801c1 100644 --- a/src/main/java/io/openliberty/tools/intellij/util/Constants.java +++ b/src/main/java/io/openliberty/tools/intellij/util/Constants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2022 IBM Corporation. + * Copyright (c) 2020, 2023 IBM Corporation. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -83,10 +83,8 @@ public final class Constants { }); /** - * Constants for langauge servers + * Constants for language servers */ - public static final String SERVER_ENV_GLOB_PATTERN = "**/{src/main/liberty/config,usr/servers/**}/server.env"; - public static final String LIBERTY_XML_SERVER = "LemMinX"; public static final String LIBERTY_CONFIG_SERVER="Liberty Config"; public static final String JAKARTA_LANG_SERVER="Eclipse LSP4Jakarta"; diff --git a/src/main/resources/META-INF/lsp.xml b/src/main/resources/META-INF/lsp.xml index 04f4afbd1..1f8e32d30 100644 --- a/src/main/resources/META-INF/lsp.xml +++ b/src/main/resources/META-INF/lsp.xml @@ -37,7 +37,7 @@ clientImpl="io.openliberty.tools.intellij.liberty.lsp.LibertyConfigLanguageClient" serverInterface="org.eclipse.lsp4mp.ls.api.MicroProfileLanguageServerAPI"/> + filePattern="**/{*.properties,*.env}"/> + + diff --git a/src/test/resources/ci/scripts/run.sh b/src/test/resources/ci/scripts/run.sh index 149ff20ab..1018a51ac 100755 --- a/src/test/resources/ci/scripts/run.sh +++ b/src/test/resources/ci/scripts/run.sh @@ -35,9 +35,9 @@ prefetchDependencies() { # Run through dev mode server install/create and feature installation for the Maven app. cd "src/test/resources/projects/maven/singleModMavenMP" - ./mvnw liberty:install-server + ./mvnw liberty:install-server -ntp ./mvnw liberty:create - ./mvnw liberty:install-feature + ./mvnw liberty:install-feature -ntp # Run through dev mode server install/create and feature installation for the Gradle app. cd "$workingDir"