From f53d912b0698637572831cdc3c6cd0b673077e7e Mon Sep 17 00:00:00 2001 From: nsingh Date: Mon, 19 Mar 2018 16:06:13 -0700 Subject: [PATCH] Possible fix for Json deserialisation bug in CF Manifest LS Note: still uses the "bad" Map structure that contains CF target params. --- .../yaml/ManifestYamlLanguageServer.java | 28 ++++++++++++++++--- .../yaml/ManifestYamlLanguageServerTest.java | 13 +++++++-- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java index c502a3830..8fdebae36 100644 --- a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java +++ b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java @@ -19,6 +19,8 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.cloudfoundry.client.ClientTimeouts; import org.springframework.ide.vscode.commons.cloudfoundry.client.CloudFoundryClientFactory; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFClientParams; @@ -35,6 +37,7 @@ import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProv import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter; 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.Settings; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; @@ -57,6 +60,9 @@ import org.yaml.snakeyaml.Yaml; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonSyntaxException; public class ManifestYamlLanguageServer extends SimpleLanguageServer { @@ -65,9 +71,11 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { private CFTargetCache cfTargetCache; private final CloudFoundryClientFactory cfClientFactory; private final CfClientConfig cfClientConfig; + private final Logger log = LoggerFactory.getLogger(ManifestYamlLanguageServer.class); private final ImmutableSet FALLBACK_YML_IDS = ImmutableSet.of(LanguageId.of("yml"), LanguageId.of("yaml")); final private ClientParamsProvider defaultClientParamsProvider; + private Gson gson = new Gson(); public ManifestYamlLanguageServer() { this(DefaultCloudFoundryClientFactoryV2.INSTANCE, CfCliParamsProvider.getInstance()); @@ -128,10 +136,10 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { documents.onHover(hoverEngine); workspace.onDidChangeConfiguraton(settings -> { - Object cfClientParamsObj = settings.getRawProperty("cfClientParams"); - //TODO code below is almost certainly broken. LSP4J doesn't return Map here but JsonObject. - if (cfClientParamsObj instanceof Map) { - applyCfLoginParameterSettings((Map) cfClientParamsObj); + //TODO code below needs to convert to a "nicer" Java representation of the CF client params, than just a Map with nested structures + Map asMap = getAs(Map.class, settings, "cfClientParams"); + if (asMap != null) { + applyCfLoginParameterSettings(asMap); } }); } @@ -140,6 +148,18 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { return cfClientConfig; } + protected T getAs(Class klass, Settings settings, String... names) { + try { + JsonElement data = settings.getRawProperty(names); + if (data != null) { + return gson.fromJson(data, klass); + } + } catch (JsonSyntaxException e) { + log.error("", e); + } + return null; + } + @SuppressWarnings("unchecked") private void applyCfLoginParameterSettings(Map cfClientParamsData) { if (cfClientParamsData.get("parameters") instanceof List) { diff --git a/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServerTest.java b/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServerTest.java index 71e6c8d35..607f5ac1c 100644 --- a/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServerTest.java +++ b/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServerTest.java @@ -15,10 +15,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import java.io.File; +import java.io.InputStreamReader; import java.net.URISyntaxException; import java.nio.file.Paths; import java.util.Arrays; -import java.util.Map; import org.eclipse.lsp4j.DidChangeConfigurationParams; import org.eclipse.lsp4j.InitializeResult; @@ -27,7 +27,10 @@ import org.junit.Test; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; public class ManifestYamlLanguageServerTest { @@ -100,7 +103,11 @@ public class ManifestYamlLanguageServerTest { assertEquals(Arrays.asList("test.io"), manifestYamlLanguageServer.getCfTargets()); DidChangeConfigurationParams params = new DidChangeConfigurationParams(); - params.setSettings(new ObjectMapper().readValue(getClass().getResourceAsStream("/cf-targets1.json"), Map.class)); + + JsonParser parser = new JsonParser(); + params.setSettings(parser.parse(new InputStreamReader(getClass().getResourceAsStream("/cf-targets1.json"))) +); + manifestYamlLanguageServer.getWorkspaceService().didChangeConfiguration(params); assertEquals(3, manifestYamlLanguageServer.getCfClientConfig().getClientParamsProvider().getParams().size()); assertEquals(Arrays.asList("test.io", "api.system.demo-gcp.springapps.io", "api.run.pivotal.io"), manifestYamlLanguageServer.getCfTargets());