Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add filewatcher to enable custom config support for LCLS #510

Merged
merged 9 commits into from
Oct 19, 2023
Merged
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Pair<Module, VirtualFile>> sources) {
// not needed for Liberty LS
public void processConfigXml(List<String> uris) {
LanguageServerWrapper wrapper = getLanguageServerWrapper();
if (wrapper != null) {
List<FileEvent> 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));
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
cherylking marked this conversation as resolved.
Show resolved Hide resolved

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<? extends VFileEvent> events) {
// filter file events to only liberty-plugin-config.xml
List<String> 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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
cherylking marked this conversation as resolved.
Show resolved Hide resolved

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

evie-lau marked this conversation as resolved.
Show resolved Hide resolved
}

public interface Listener {
void processConfigXml(List<String> uris);
}

public static LibertyCustomConfigManager getInstance(Project project) {
evie-lau marked this conversation as resolved.
Show resolved Hide resolved
return project.getService(LibertyCustomConfigManager.class);
}

public static final Topic<Listener> TOPIC = Topic.create(LibertyCustomConfigManager.class.getName(), Listener.class);


public LibertyCustomConfigManager(Project project) {
this.project = project;
LibraryTablesRegistrar.getInstance().getLibraryTable(project).addListener(this, project);
listener = new LibertyCustomConfigListener(this);
appConnection = ApplicationManager.getApplication().getMessageBus().connect(project);
appConnection.subscribe(VirtualFileManager.VFS_CHANGES, listener);
}

protected void handleProcessConfigXml(List<String> uris) {
project.getMessageBus().syncPublisher(TOPIC).processConfigXml(uris);
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
Expand All @@ -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
*/
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,11 @@ 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());
// }
// else {
// LOGGER.warn(message.getClass().getSimpleName() + ": " + this.serverDefinition.id + '\n' + message.toString());
// }
evie-lau marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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";
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/META-INF/lsp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
clientImpl="io.openliberty.tools.intellij.liberty.lsp.LibertyConfigLanguageClient"
serverInterface="org.eclipse.lsp4mp.ls.api.MicroProfileLanguageServerAPI"/>
<languageMapping language="Properties" serverId="libertyls"
filePattern="**/{src/main/liberty/config,usr/servers/**}/{bootstrap.properties,server.env}"/>
filePattern="**/{*.properties,*.env}"/>

<!-- Jakarta LS -->
<server id="jakartals" class="io.openliberty.tools.intellij.lsp4jakarta.lsp.JakartaLanguageServer"
Expand All @@ -64,6 +64,8 @@
<inspectionToolProvider
implementation="io.openliberty.tools.intellij.lsp4mp.lsp4ij.operations.diagnostics.LSPInspectionToolProvider"/>
<projectService serviceImplementation="io.openliberty.tools.intellij.lsp4mp.lsp4ij.LanguageServiceAccessor"/>
<!-- Enable watcher to handle custom liberty config files and provide LCLS support -->
<projectService serviceImplementation="io.openliberty.tools.intellij.liberty.lsp.LibertyCustomConfigManager"/>
<!-- TODO re-enable goto handler -->
<!-- <gotoDeclarationHandler
implementation="io.openliberty.tools.intellij.lsp4mp.lsp4ij.operations.navigation.LSPGotoDeclarationHandler"/> -->
Expand Down
Loading