From aa2e89f0ddde45298439344e551c3be045a419ec Mon Sep 17 00:00:00 2001 From: nsingh Date: Tue, 5 Jun 2018 15:26:55 -0700 Subject: [PATCH] PT 156967558 - Replace ObjectMapper with Gson in Bosh LS --- .../models/BoshCommandBasedModelProvider.java | 28 ++++++---- .../models/BoshCommandReleasesProvider.java | 2 +- .../models/BoshCommandStemcellsProvider.java | 2 +- .../ide/vscode/bosh/models/JSONCursor.java | 23 ++++---- .../ide/vscode/bosh/BoshEditorTest.java | 7 +-- .../ide/vscode/commons/util/GsonUtil.java | 55 +++++++++++++++++++ .../ide/vscode/commons}/util/Streams.java | 2 +- .../yaml/completion/AppendTextBuilder.java | 4 +- .../yaml/path/AbstractYamlTraversal.java | 4 +- .../yaml/path/AlternativeYamlTraversal.java | 3 +- .../yaml/path/RepeatingYamlTraversal.java | 4 +- .../yaml/structure/YamlStructureParser.java | 4 +- 12 files changed, 99 insertions(+), 39 deletions(-) create mode 100644 headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/GsonUtil.java rename headless-services/commons/{commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml => commons-util/src/main/java/org/springframework/ide/vscode/commons}/util/Streams.java (95%) diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandBasedModelProvider.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandBasedModelProvider.java index a3e7977c5..1ab0d9979 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandBasedModelProvider.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandBasedModelProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -32,10 +32,10 @@ import org.springframework.ide.vscode.commons.yaml.path.YamlTraversal; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.representer.Representer; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.annotations.SerializedName; /** * Abstract base class to aid in implementing a Dynamic model provider that executes a bosh @@ -44,7 +44,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; public abstract class BoshCommandBasedModelProvider implements DynamicModelProvider { private final YamlParser yamlParser; - protected final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + // NOTE: By default, Gson skips unknown fields, so this hopefully is equivalent to the Jackson mapper configuration that was replaced: + // protected final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + protected final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + private final BoshCliConfig config; protected BoshCommandBasedModelProvider(BoshCliConfig config) { @@ -58,12 +62,13 @@ public abstract class BoshCommandBasedModelProvider implements DynamicModelPr * For deserializing the output from bosh cloud-config command. */ public static class BoshCommandResponse { + @SerializedName("Blocks") private String[] blocks; - @JsonProperty("Blocks") public String[] getBlocks() { return blocks; } + public void setBlocks(String[] blocks) { this.blocks = blocks; } @@ -71,7 +76,7 @@ public abstract class BoshCommandBasedModelProvider implements DynamicModelPr protected String getBlock() throws Exception { String out = executeCommand(getCommand()); - BoshCommandResponse response = mapper.readValue(out, BoshCommandResponse.class); + BoshCommandResponse response = gson.fromJson(out, BoshCommandResponse.class); String[] blocks = response.getBlocks(); Assert.isLegal(blocks!=null); Assert.isLegal(blocks.length==1); @@ -100,9 +105,10 @@ public abstract class BoshCommandBasedModelProvider implements DynamicModelPr return new ExternalCommand(commandAndArgs.toArray(new String[commandAndArgs.size()])); } - protected JsonNode getJsonTree() throws Exception { + protected JsonElement getJsonTree() throws Exception { String out = executeCommand(getCommand()); - return mapper.readTree(out); + JsonElement element = gson.fromJson(out, JsonElement.class); + return element; } protected String executeCommand(ExternalCommand command) throws Exception { @@ -137,7 +143,7 @@ public abstract class BoshCommandBasedModelProvider implements DynamicModelPr protected Collection getNames(JSONCursor _cursor, YamlTraversal path) { return path.traverseAmbiguously(_cursor) .flatMap((cursor) -> { - String text = cursor.target.asText(); + String text = cursor.target.getAsString(); if (StringUtil.hasText(text)) { return Stream.of(text); } else { diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandReleasesProvider.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandReleasesProvider.java index 97a8a7a24..9f017e048 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandReleasesProvider.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandReleasesProvider.java @@ -56,7 +56,7 @@ public class BoshCommandReleasesProvider extends BoshCommandBasedModelProvider< private String getStringProperty(JSONCursor c, String prop) { c = YamlPath.EMPTY.thenValAt(prop).traverse(c); if (c!=null) { - return c.target.asText(); + return c.target.getAsString(); } return null; } diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandStemcellsProvider.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandStemcellsProvider.java index c0c337842..723cd3eab 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandStemcellsProvider.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/BoshCommandStemcellsProvider.java @@ -64,7 +64,7 @@ public class BoshCommandStemcellsProvider extends BoshCommandBasedModelProvider< private String getStringProperty(JSONCursor c, String prop) { c = YamlPath.EMPTY.thenValAt(prop).traverse(c); if (c!=null) { - return c.target.asText(); + return c.target.getAsString(); } return null; } diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/JSONCursor.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/JSONCursor.java index 30ee9213b..4e68244b4 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/JSONCursor.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/JSONCursor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,21 +12,22 @@ package org.springframework.ide.vscode.bosh.models; import java.util.stream.Stream; +import org.springframework.ide.vscode.commons.util.GsonUtil; import org.springframework.ide.vscode.commons.yaml.path.YamlNavigable; import org.springframework.ide.vscode.commons.yaml.path.YamlPath; import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment; -import org.springframework.ide.vscode.commons.yaml.util.Streams; -import com.fasterxml.jackson.databind.JsonNode; +import com.google.gson.JsonElement; + /** - * Allows using {@link YamlPath} / {@link YamlNavigable} on {@link JsonNode}s + * Allows using {@link YamlPath} / {@link YamlNavigable} */ public class JSONCursor implements YamlNavigable { - public final JsonNode target; + public final JsonElement target; - public JSONCursor(JsonNode target) { + public JSONCursor(JsonElement target) { super(); this.target = target; } @@ -36,22 +37,22 @@ public class JSONCursor implements YamlNavigable { return oneStep(s).map(JSONCursor::new); } - private Stream oneStep(YamlPathSegment s) { + private Stream oneStep(YamlPathSegment s) { if (target==null) { return Stream.empty(); } switch (s.getType()) { case KEY_AT_KEY: { - return Streams.fromNullable(target.get(s.toPropString())); + return GsonUtil.getFromKey(target, s.toPropString()); } case ANY_CHILD: { - return Streams.fromIterable(target); + return GsonUtil.getFromElements(target); } case VAL_AT_INDEX: { - return Streams.fromNullable(target.get(s.toIndex())); + return GsonUtil.getFromIndex(target, s.toIndex()); } case VAL_AT_KEY: { - return Streams.fromNullable(target.get(s.toPropString())); + return GsonUtil.getFromKey(target, s.toPropString()); } default: throw new IllegalStateException("Missing case for "+s.getType()); diff --git a/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java b/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java index 2e05bd275..b8f83c528 100644 --- a/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java +++ b/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java @@ -17,6 +17,7 @@ import static org.mockito.Mockito.when; import static org.springframework.ide.vscode.languageserver.testharness.Editor.DEDENTED_COMPLETION; import static org.springframework.ide.vscode.languageserver.testharness.Editor.PLAIN_COMPLETION; import static org.springframework.ide.vscode.languageserver.testharness.Editor.SNIPPET_COMPLETION; +import static org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness.getDocString; import static org.springframework.ide.vscode.languageserver.testharness.TestAsserts.assertContains; import java.io.IOException; @@ -46,8 +47,6 @@ import org.springframework.ide.vscode.languageserver.testharness.LanguageServerH import com.google.common.collect.ImmutableMultiset; import com.google.common.collect.ImmutableSet; -import static org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness.*; - public class BoshEditorTest { LanguageServerHarness harness; @@ -1155,7 +1154,7 @@ public class BoshEditorTest { return new BoshCommandStemcellsProvider(cliConfig) { @Override protected String executeCommand(ExternalCommand command) throws Exception { - String rows = mapper.writeValueAsString(stemcellData); + String rows = gson.toJson(stemcellData); return "{\n" + " \"Tables\": [\n" + " {\n" + @@ -1324,7 +1323,7 @@ public class BoshEditorTest { return new BoshCommandReleasesProvider(cliConfig) { @Override protected String executeCommand(ExternalCommand command) throws Exception { - String rows = mapper.writeValueAsString(stemcellData); + String rows = gson.toJson(stemcellData); return "{\n" + " \"Tables\": [\n" + " {\n" + diff --git a/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/GsonUtil.java b/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/GsonUtil.java new file mode 100644 index 000000000..16bac0632 --- /dev/null +++ b/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/GsonUtil.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2018 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Stream; + +import com.google.gson.JsonElement; + +public class GsonUtil { + + public static Stream getFromElements(JsonElement target) { + if (target.isJsonArray()) { + return Streams.fromIterable(target.getAsJsonArray()); + } else if (target.isJsonObject()) { + List vals = new ArrayList<>(); + Set> entrySet = target.getAsJsonObject().entrySet(); + if (entrySet != null) { + for (Entry entry : entrySet) { + vals.add(entry.getValue()); + } + } + return vals.stream(); + } else { + return Stream.empty(); + } + } + + public static Stream getFromIndex(JsonElement target, int index) { + if (target.isJsonArray()) { + return Streams.fromNullable(target.getAsJsonArray().get(index)); + } else { + return Stream.empty(); + } + } + + public static Stream getFromKey(JsonElement target, String key) { + if (target.isJsonObject()) { + return Streams.fromNullable(target.getAsJsonObject().get(key)); + } else { + return Stream.empty(); + } + } +} diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/util/Streams.java b/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Streams.java similarity index 95% rename from headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/util/Streams.java rename to headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Streams.java index 077b0cb6f..51e96716f 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/util/Streams.java +++ b/headless-services/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Streams.java @@ -8,7 +8,7 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ -package org.springframework.ide.vscode.commons.yaml.util; +package org.springframework.ide.vscode.commons.util; import java.util.ArrayList; import java.util.stream.Collectors; diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AppendTextBuilder.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AppendTextBuilder.java index 80cbca01b..c041755c5 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AppendTextBuilder.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AppendTextBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,10 +10,10 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.yaml.completion; +import org.springframework.ide.vscode.commons.util.Streams; import org.springframework.ide.vscode.commons.yaml.schema.YType; import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil; import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty; -import org.springframework.ide.vscode.commons.yaml.util.Streams; import org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil; /** diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AbstractYamlTraversal.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AbstractYamlTraversal.java index 4f0472af0..156b05e94 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AbstractYamlTraversal.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AbstractYamlTraversal.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,7 +12,7 @@ package org.springframework.ide.vscode.commons.yaml.path; import java.util.stream.Stream; -import org.springframework.ide.vscode.commons.yaml.util.Streams; +import org.springframework.ide.vscode.commons.util.Streams; /** * Abstract superclass for implementing concrete {@link YamlTraversal}s. diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AlternativeYamlTraversal.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AlternativeYamlTraversal.java index d7e84d125..3e3cc6626 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AlternativeYamlTraversal.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/AlternativeYamlTraversal.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,7 +13,6 @@ package org.springframework.ide.vscode.commons.yaml.path; import java.util.stream.Stream; import org.springframework.ide.vscode.commons.util.Assert; -import org.springframework.ide.vscode.commons.yaml.util.Streams; public class AlternativeYamlTraversal extends AbstractYamlTraversal { diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/RepeatingYamlTraversal.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/RepeatingYamlTraversal.java index b1b5be312..6206a921e 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/RepeatingYamlTraversal.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/RepeatingYamlTraversal.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,7 +13,7 @@ package org.springframework.ide.vscode.commons.yaml.path; import java.util.stream.Stream; import org.springframework.ide.vscode.commons.util.Assert; -import org.springframework.ide.vscode.commons.yaml.util.Streams; +import org.springframework.ide.vscode.commons.util.Streams; public class RepeatingYamlTraversal extends AbstractYamlTraversal { diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/structure/YamlStructureParser.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/structure/YamlStructureParser.java index 8d14f2bef..92cbe47b1 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/structure/YamlStructureParser.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/structure/YamlStructureParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2017 Pivotal, Inc. + * Copyright (c) 2016, 2018 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -25,6 +25,7 @@ import java.util.stream.Stream; import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.commons.util.CollectionUtil; import org.springframework.ide.vscode.commons.util.Log; +import org.springframework.ide.vscode.commons.util.Streams; import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.text.IDocument; import org.springframework.ide.vscode.commons.util.text.IRegion; @@ -32,7 +33,6 @@ import org.springframework.ide.vscode.commons.yaml.path.KeyAliases; import org.springframework.ide.vscode.commons.yaml.path.YamlNavigable; import org.springframework.ide.vscode.commons.yaml.path.YamlPath; import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment; -import org.springframework.ide.vscode.commons.yaml.util.Streams; import org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil; import com.google.common.collect.ImmutableList;