Skip to content

Commit

Permalink
fix YAML properties schema registration
Browse files Browse the repository at this point in the history
Signed-off-by: Stephane Bouchet <[email protected]>
  • Loading branch information
sbouchet committed Oct 9, 2023
1 parent 78d6c28 commit bd8b141
Showing 1 changed file with 27 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.tuple.MutablePair;
Expand All @@ -33,16 +31,12 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4e.LanguageServerWrapper;
import org.eclipse.lsp4e.LanguageServers;
import org.eclipse.lsp4e.LanguageServersRegistry;
import org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition;
import org.eclipse.lsp4e.LanguageServiceAccessor;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.services.LanguageServer;
import org.eclipse.lsp4mp.commons.ClasspathKind;
import org.eclipse.lsp4mp.commons.DocumentFormat;
import org.eclipse.lsp4mp.commons.MicroProfileProjectInfo;
Expand All @@ -52,13 +46,9 @@
import org.eclipse.lsp4mp.jdt.core.PropertiesManager;
import org.eclipse.lsp4mp.jdt.internal.core.MicroProfilePropertiesListenerManager;
import org.eclipse.lsp4mp.utils.JSONSchemaUtils;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.jboss.tools.quarkus.lsp4e.QuarkusLSPPlugin;
import org.jboss.tools.quarkus.lsp4e.internal.ls.JDTUtilsImpl;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
* @author Red Hat Developers
*
Expand All @@ -81,7 +71,7 @@ private SchemaRegistry() {
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_CLOSE);
}

private void updateYAMLLanguageServerConfigIfRequired(IProject project, boolean sendToServer) {
public void updateYAMLLanguageServerConfigIfRequired(IProject project) {
try {
MutablePair<File, Boolean> schemaEntry = schemas.get(project);
if (schemaEntry == null || !schemaEntry.getRight()) {
Expand All @@ -93,92 +83,54 @@ private void updateYAMLLanguageServerConfigIfRequired(IProject project, boolean
schemas.put(project, schemaEntry);
}
}
if (sendToServer) {
sendInitialize(project);
}
sendInitialize(project);
} catch (CoreException | IOException e) {
QuarkusLSPPlugin.logException(e.getLocalizedMessage(), e);
}
}

public void updateYAMLLanguageServerConfigIfRequired(IProject project) {
updateYAMLLanguageServerConfigIfRequired(project, true);
}

private void sendInitialize(IProject project) throws IOException {
LanguageServerDefinition def = LanguageServersRegistry.getInstance()
.getDefinition("org.eclipse.wildwebdeveloper.yaml");
LanguageServerWrapper server = LanguageServiceAccessor.getLSWrapper(project, def);
Map<String, Object> prefs = new HashMap<>();
prefs.put("schemas", schemas2YAMLLSMap());
prefs.put("completion", true);
prefs.put("hover", true);
prefs.put("validate", true);
DidChangeConfigurationParams params = new DidChangeConfigurationParams(Collections.singletonMap("yaml", prefs));
Function<LanguageServer, CompletableFuture<Void>> fn = new Function<>() {

@Override
public CompletableFuture<Void> apply(LanguageServer ls) {
ls.getWorkspaceService().didChangeConfiguration(params);
return CompletableFuture.completedFuture(null);
}
};
server.execute(fn);

Map<String, Object> settings = new HashMap<>();
Map<String, Object> yaml = new HashMap<>();
yaml.put("schemas", schemas2YAMLLSMap());
settings.put("yaml", yaml);

DidChangeConfigurationParams params = new DidChangeConfigurationParams(settings);
LanguageServers.forProject(project).withPreferredServer(def).excludeInactive()
.collectAll((w, ls) -> CompletableFuture.completedFuture(ls))
.thenAccept(lss -> lss.stream().forEach(ls -> ls.getWorkspaceService().didChangeConfiguration(params)));
}

private Map<String, Object> schemas2YAMLLSMap() {
Map<String, Object> config = loadFromYAMLLS();
Map<String, Object> config = new HashMap<>();
schemas.forEach(
(project, entry) -> config.put(LSPEclipseUtils.toUri(entry.getLeft()).toString(), getPattern(project)));
(project, entry) -> config.put(LSPEclipseUtils.toUri(entry.getLeft()).toString(), "application.y*ml"));
return config;
}

private String[] getPattern(IProject project) {
String[] patterns = new String[2];
String projectRoot = LSPEclipseUtils.toUri(project).toString();
patterns[0] = projectRoot + "*/application.yaml";
patterns[1] = projectRoot + "*/application.yml";
return patterns;
}

/**
* Get the YAML LS default schemas config.
*
* @see <a href=
* "https://github.com/eclipse/wildwebdeveloper/blob/master/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/yaml/YAMLLanguageServer.java"/>https://github.com/eclipse/wildwebdeveloper/blob/master/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/yaml/YAMLLanguageServer.java
* @return
*/
private Map<String, Object> loadFromYAMLLS() {
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
"org.eclipse.wildwebdeveloper");
String schemaStr = preferenceStore.getString("wildwebdeveloper.yaml.schema");
if (schemaStr != null) {
Map<String, Object> result = new Gson().fromJson(schemaStr, new TypeToken<HashMap<String, Object>>() {
}.getType());
return result == null ? Collections.emptyMap() : result;
}
return Collections.emptyMap();
}

/**
* @param project
* @return
* @throws IOException
*/
private File computeSchema(IProject project, File f) throws CoreException, IOException {
File tmpFile;
if (f == null) {
f = File.createTempFile(project.getName() + "-schema", ".json");
tmpFile = File.createTempFile(project.getName() + "-schema", ".json");
} else {
tmpFile = f;
}
MicroProfileProjectInfo projectInfo = PropertiesManager.getInstance().getMicroProfileProjectInfo(
JavaCore.create(project), MicroProfilePropertiesScope.SOURCES_AND_DEPENDENCIES, ClasspathKind.SRC,
JDTUtilsImpl.getInstance(), DocumentFormat.Markdown, new NullProgressMonitor());

String schemaStr = JSONSchemaUtils.toJSONSchema(projectInfo, false);
try (Writer w = new FileWriter(f)) {
try (Writer w = new FileWriter(tmpFile)) {
IOUtils.write(schemaStr, w);
}
return f;
return tmpFile;
}

@Override
Expand All @@ -199,12 +151,7 @@ public void propertiesChanged(MicroProfilePropertiesChangeEvent event) {
}
if (!projects.isEmpty()) {
for (IProject project : projects) {
updateYAMLLanguageServerConfigIfRequired(project, false);
try {
sendInitialize(project);
} catch (IOException e) {
QuarkusLSPPlugin.logException(e.getLocalizedMessage(), e);
}
updateYAMLLanguageServerConfigIfRequired(project);
}
}
}
Expand All @@ -215,4 +162,10 @@ public void resourceChanged(IResourceChangeEvent event) {
schemas.remove(event.getResource());
}
}

private class YamlConfig extends HashMap<String, Object> {

Map<String, List<String>> schemas;

}
}

0 comments on commit bd8b141

Please sign in to comment.