PT 156967558 - Replace ObjectMapper with Gson in Bosh LS

This commit is contained in:
nsingh
2018-06-05 15:26:55 -07:00
parent ac145815e3
commit aa2e89f0dd
12 changed files with 99 additions and 39 deletions

View File

@@ -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<T> implements DynamicModelProvider<T> {
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<T> 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<T> 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<T> 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<T> implements DynamicModelPr
protected Collection<String> 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 {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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<JSONCursor> {
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<JSONCursor> {
return oneStep(s).map(JSONCursor::new);
}
private Stream<JsonNode> oneStep(YamlPathSegment s) {
private Stream<JsonElement> 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());

View File

@@ -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<BoshLanguageServer> 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" +

View File

@@ -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<JsonElement> getFromElements(JsonElement target) {
if (target.isJsonArray()) {
return Streams.fromIterable(target.getAsJsonArray());
} else if (target.isJsonObject()) {
List<JsonElement> vals = new ArrayList<>();
Set<Entry<String, JsonElement>> entrySet = target.getAsJsonObject().entrySet();
if (entrySet != null) {
for (Entry<String, JsonElement> entry : entrySet) {
vals.add(entry.getValue());
}
}
return vals.stream();
} else {
return Stream.empty();
}
}
public static Stream<JsonElement> getFromIndex(JsonElement target, int index) {
if (target.isJsonArray()) {
return Streams.fromNullable(target.getAsJsonArray().get(index));
} else {
return Stream.empty();
}
}
public static Stream<JsonElement> getFromKey(JsonElement target, String key) {
if (target.isJsonObject()) {
return Streams.fromNullable(target.getAsJsonObject().get(key));
} else {
return Stream.empty();
}
}
}

View File

@@ -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;

View File

@@ -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;
/**

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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;