Allow preferences to be an array of serializable values.

7.20.x
Max Shaposhnik 2020-04-24 14:17:57 +03:00 committed by GitHub
parent 168988ac3b
commit b4901eee6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 135 additions and 12 deletions

View File

@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
@ -50,6 +51,36 @@ public class PreferencesDeserializer extends JsonDeserializer<Map<String, Serial
case VALUE_STRING:
result.put(jsonParser.getCurrentName(), jsonParser.getValueAsString());
break;
case START_ARRAY:
String key = jsonParser.getCurrentName();
ArrayList<Serializable> array = new ArrayList<>();
// Iterate over nested array
JsonToken nextValue = jsonParser.nextValue();
while (!JsonToken.END_ARRAY.equals(nextValue)) {
switch (nextValue) {
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
array.add(jsonParser.getNumberValue());
break;
case VALUE_FALSE:
case VALUE_TRUE:
array.add(jsonParser.getValueAsBoolean());
break;
case VALUE_STRING:
array.add(jsonParser.getValueAsString());
break;
default:
throw new JsonParseException(
jsonParser,
format(
"Unexpected value in the nested array of the preference with key '%s'.",
key));
}
nextValue = jsonParser.nextValue();
}
result.put(key, array.toArray());
break;
default:
throw new JsonParseException(
jsonParser,

View File

@ -12,9 +12,12 @@
package org.eclipse.che.api.workspace.server.devfile;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.eclipse.che.api.core.model.workspace.devfile.Component;
@ -47,9 +50,30 @@ public class SerializableConverter implements AttributeConverter<Serializable, S
@Override
public Serializable convertToEntityAttribute(String dbData) {
try {
return objectMapper.readValue(dbData, Serializable.class);
JsonNode node = objectMapper.readTree(dbData);
if (node.isValueNode()) {
return serializableNodeValue(node);
} else if (node.isArray()) {
List<Serializable> values = new ArrayList<>();
node.elements().forEachRemaining(n -> values.add(serializableNodeValue(n)));
return values.toArray();
} else {
throw new RuntimeException("Unable to deserialize preference value:" + dbData);
}
} catch (IOException e) {
throw new RuntimeException("Unable to deserialize preference value:" + e.getMessage(), e);
}
}
private Serializable serializableNodeValue(JsonNode node) {
if (node.isNumber()) {
return node.numberValue();
} else if (node.isBoolean()) {
return node.booleanValue();
} else if (node.isTextual()) {
return node.textValue();
} else {
throw new RuntimeException("Unable to deserialize preference value:" + node.asText());
}
}
}

View File

@ -347,10 +347,24 @@
"{\"java.home\": \"/home/user/jdk11\", \"java.jdt.ls.vmargs\": \"-Xmx1G\"}"
],
"additionalProperties": {
"type": [
"boolean",
"string",
"number"
"anyOf" : [
{
"type": [
"boolean",
"string",
"number"
]
},
{
"type": "array",
"items": {
"type": [
"boolean",
"string",
"number"
]
}
}
]
}
}

View File

@ -12,7 +12,6 @@
package org.eclipse.che.api.workspace.server.devfile;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
@ -42,16 +41,22 @@ public class PreferencesDeserializerTest {
+ "\"valid.string\": \"/usr/bin/value\","
+ "\"valid.boolean\": false,"
+ "\"valid.integer\": 777555888,"
+ "\"valid.float\": 3.1415926"
+ "\"valid.float\": 3.1415926,"
+ "\"valid.string.array\": [\"foo\",\"bar\",\"baz\"],"
+ "\"valid.int.array\": [12,13,0],"
+ "\"valid.bool.array\": [true,false,false]"
+ "}";
final JsonParser parser = factory.createParser(json);
Map<String, Serializable> result = preferencesDeserializer.deserialize(parser, ctxt);
assertEquals(4, result.size());
assertTrue(result.containsValue(777555888));
assertTrue(result.containsValue(3.1415926));
assertTrue(result.containsValue(false));
assertTrue(result.containsValue("/usr/bin/value"));
assertEquals(7, result.size());
assertEquals(result.get("valid.integer"), 777555888);
assertEquals(result.get("valid.float"), 3.1415926);
assertEquals(result.get("valid.boolean"), false);
assertEquals(result.get("valid.string"), "/usr/bin/value");
assertEquals(result.get("valid.string.array"), new String[] {"foo", "bar", "baz"});
assertEquals(result.get("valid.int.array"), new int[] {12, 13, 0});
assertEquals(result.get("valid.bool.array"), new boolean[] {true, false, false});
}
@Test(

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.workspace.server.devfile;
import static org.testng.Assert.assertEquals;
import java.io.Serializable;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class SerializableConverterTest {
private final SerializableConverter converter = new SerializableConverter();
@DataProvider
public static Object[][] SerializableProvider() {
return new Object[][] {
{"foo"},
{"bar"},
{true},
{false},
{Integer.MAX_VALUE},
{0},
{Integer.MIN_VALUE},
{"{\"java.home\": \"/home/user/jdk11\", \"java.jdt.ls.vmargs\": \"-Xmx1G\"}"},
{new String[] {"single"}},
{new String[] {"--enable-all", "--new"}},
{new int[] {213, 456, 459}},
{new boolean[] {true, false, false}}
};
}
@Test(dataProvider = "SerializableProvider")
public void testConvertToDatabaseColumnAndBack(Serializable initialObj) {
String res = converter.convertToDatabaseColumn(initialObj);
Serializable backObj = converter.convertToEntityAttribute(res);
assertEquals(initialObj, backObj);
}
}

View File

@ -20,3 +20,4 @@ components:
java.home: '/home/user/jdk11'
java.jdt.ls.vmargs: '-noverify -Xmx1G -XX:+UseG1GC -XX:+UseStringDeduplication'
java.jtg.memory: 12345
go.lintFlags: ["--enable-all", "--new"]