From a3d2516685b3dda8303adf8f46c6170ad0cfdb7b Mon Sep 17 00:00:00 2001 From: Dmitry Kuleshov Date: Wed, 19 Apr 2017 17:40:13 +0300 Subject: [PATCH] Fixes cases where we send primitive values over Json RPC (#4751) Signed-off-by: Dmitry Kuleshov --- .../che/api/core/jsonrpc/JsonRpcFactory.java | 11 - .../che/api/core/jsonrpc/JsonRpcParams.java | 149 ++++++++++--- .../core/jsonrpc/RequestHandlerOneToMany.java | 6 +- .../core/jsonrpc/RequestHandlerOneToOne.java | 6 +- .../SendConfiguratorFromMany.java | 4 +- .../api/core/jsonrpc/JsonRpcParamsTest.java | 39 ++-- .../che/ide/jsonrpc/JsonRpcFactory.java | 11 - .../che/ide/jsonrpc/JsonRpcParams.java | 207 ++++++++++-------- .../ide/jsonrpc/RequestHandlerOneToList.java | 6 +- .../ide/jsonrpc/RequestHandlerOneToOne.java | 6 +- .../SendConfiguratorFromList.java | 5 +- .../che/ide/jsonrpc/JsonRpcParamsTest.java | 31 +-- 12 files changed, 293 insertions(+), 188 deletions(-) diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcFactory.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcFactory.java index d4894737a39..ceff567b85a 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcFactory.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcFactory.java @@ -187,15 +187,4 @@ JsonRpcResponse createResponse(@Assisted("id") String id, @Assisted("result") Js * @return JSON RPC params */ JsonRpcParams createParams(@Assisted("params") Object params); - - /** - * Create a JSON RPC params instance by passing corresponding values. - * Params should be represented by a list of objects. - * - * @param params - * params list - * - * @return JSON RPC params - */ - JsonRpcParams createParamsList(@Assisted("params") List params); } diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParams.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParams.java index dc617cd062c..b17f05e260f 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParams.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParams.java @@ -21,88 +21,185 @@ import org.eclipse.che.dto.server.DtoFactory; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static org.eclipse.che.api.core.jsonrpc.JsonRpcUtils.cast; /** * Represents JSON RPC params object. Can be constructed out of * stringified json object or by passing specific parameters. * Use {@link JsonRpcFactory#createParams(Object)}, - * {@link JsonRpcFactory#createParamsList(List)} or * {@link JsonRpcFactory#createParams(String)} to get an instance. */ public class JsonRpcParams { - private final static JsonObject EMPTY_OBJECT = new JsonObject(); + private final JsonParser jsonParser; - private List paramsList; - private JsonElement params; + private List> params; + private Param param; @AssistedInject public JsonRpcParams(@Assisted("message") String message, JsonParser jsonParser) { + this.jsonParser = jsonParser; + checkNotNull(message, "Message must not be null"); checkArgument(!message.isEmpty(), "Message must not be empty"); JsonElement jsonElement = jsonParser.parse(message); if (jsonElement.isJsonArray()) { JsonArray jsonArray = jsonParser.parse(message).getAsJsonArray(); - paramsList = new ArrayList<>(jsonArray.size()); - jsonArray.forEach(it -> paramsList.add(it)); + this.params = new ArrayList<>(jsonArray.size()); + for (JsonElement element : jsonArray) { + if (element.isJsonPrimitive()) { + JsonPrimitive primitiveElement = element.getAsJsonPrimitive(); + Param paramCandidate; + if (primitiveElement.isBoolean()) { + paramCandidate = new Param<>(Boolean.class, primitiveElement.getAsBoolean()); + } else if (primitiveElement.isNumber()) { + paramCandidate = new Param<>(Double.class, primitiveElement.getAsDouble()); + } else { + paramCandidate = new Param<>(String.class, primitiveElement.getAsString()); + } + this.params.add(paramCandidate); + } else { + this.params.add(new Param<>(Object.class, element.getAsJsonObject())); + } + } + + this.param = null; + } else if (jsonElement.isJsonPrimitive()) { + JsonPrimitive primitiveElement = jsonElement.getAsJsonPrimitive(); + if (primitiveElement.isBoolean()) { + this.param = new Param<>(Boolean.class, primitiveElement.getAsBoolean()); + } else if (primitiveElement.isNumber()) { + this.param = new Param<>(Double.class, primitiveElement.getAsDouble()); + } else { + this.param = new Param<>(String.class, primitiveElement.getAsString()); + } + + this.params = null; + } else if (jsonElement.isJsonObject()) { + this.param = new Param<>(Object.class, jsonElement.getAsJsonObject()); + + this.params = null; } else { - params = jsonParser.parse(message); + this.params = null; + this.param = null; } } - @AssistedInject - public JsonRpcParams(@Assisted("params") Object params, JsonParser jsonParser) { - this.params = params == null ? EMPTY_OBJECT : jsonParser.parse(params.toString()); - } @AssistedInject - public JsonRpcParams(JsonParser jsonParser, @Assisted("params") List params) { - if (params == null || params.isEmpty()) { - this.paramsList = Collections.emptyList(); + public JsonRpcParams(JsonParser jsonParser, @Assisted("params") Object params) { + this.jsonParser = jsonParser; + + if (params == null) { + this.params = null; + this.param = null; } else { - // ugly workaround will be fixed in next release - if (params.get(0) instanceof String) { - this.paramsList = params.stream().map(it -> new JsonPrimitive(it.toString())).collect(Collectors.toList()); + if (params instanceof List) { + List listParams = (List)params; + this.params = new ArrayList<>(listParams.size()); + + for (Object param : listParams) { + Param paramCandidate; + if (param instanceof Boolean) { + paramCandidate = new Param<>(Boolean.class, (Boolean)param); + } else if (param instanceof String) { + paramCandidate = new Param<>(String.class, (String)param); + } else if (param instanceof Double) { + paramCandidate = new Param<>(Double.class, (Double)param); + } else { + paramCandidate = new Param<>(Object.class, param); + } + this.params.add(paramCandidate); + } + + this.param = null; } else { - this.paramsList = params.stream().map(Object::toString).map(jsonParser::parse).collect(Collectors.toList()); + Param paramCandidate; + if (params instanceof Boolean) { + this.param = new Param<>(Boolean.class, (Boolean)params); + } else if (params instanceof String) { + this.param = new Param<>(String.class, (String)params); + } else if (params instanceof Double) { + this.param = new Param<>(Double.class, (Double)params); + } else { + this.param = new Param<>(Object.class, params); + } + + this.params = null; } } } public boolean emptyOrAbsent() { - return (paramsList == null || paramsList.isEmpty()) && (params == null || EMPTY_OBJECT.equals(params)); + return (params == null || params.isEmpty()) && (param == null || jsonParser.parse("{}").equals(param.value)); } public JsonElement toJsonElement() { - if (params != null) { - return params; + if (param != null) { + if (param.type.equals(Object.class)) { + return jsonParser.parse(param.value.toString()); + } else if (param.type.equals(String.class)) { + return new JsonPrimitive((String)param.value); + } else if (param.type.equals(Boolean.class)) { + return new JsonPrimitive((Boolean)param.value); + } else if (param.type.equals(Double.class)) { + return new JsonPrimitive((Double)param.value); + } } JsonArray array = new JsonArray(); - paramsList.forEach(array::add); + for (Param paramCandidate : params) { + JsonElement element; + if (paramCandidate.type.equals(Object.class)) { + element = jsonParser.parse(paramCandidate.value.toString()); + } else if (paramCandidate.type.equals(String.class)) { + element = new JsonPrimitive((String)paramCandidate.value); + } else if (paramCandidate.type.equals(Boolean.class)) { + element = new JsonPrimitive((Boolean)paramCandidate.value); + } else { + element = new JsonPrimitive((Double)paramCandidate.value); + } + array.add(element); + } return array; } public T getAs(Class type) { - checkNotNull(params, "Type must not be null"); + checkNotNull(type, "Type must not be null"); + checkNotNull(param, "Param must not be null"); + checkState(type.equals(param.type), "Types should match"); - return JsonRpcUtils.getAs(params, type); + if (param.type.equals(Object.class)) { + return DtoFactory.getInstance().createDtoFromJson(param.value.toString(), type); + } else { + return cast(param.value); + } } public List getAsListOf(Class type) { checkNotNull(type, "Type must not be null"); - return JsonRpcUtils.getAsListOf(paramsList, type); + return params.stream().map(it -> it.value).collect(cast(Collectors.toList())); } @Override public String toString() { return toJsonElement().toString(); } + + private class Param { + final private Class type; + final private T value; + + private Param(Class type, T value) { + this.type = type; + this.value = value; + } + } } diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToMany.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToMany.java index c9cb4b6bf9d..e277d600b1c 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToMany.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToMany.java @@ -53,7 +53,11 @@ public JsonRpcResult handle(String endpointId, JsonRpcParams params) throws Json LOG.debug("Handling request from: {}, with params: {}", endpointId, params); - P paramsObject = params.getAs(pClass); + P paramsObject = pClass.equals(String.class) || + pClass.equals(Boolean.class) || + pClass.equals(Double.class) ? params.getAsListOf(pClass).get(0) + : params.getAs(pClass); + LOG.debug("Created raw params object: {}", paramsObject); List resultList = function.apply(endpointId, paramsObject); LOG.debug("Received result list: {}", resultList); diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToOne.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToOne.java index 8c5b95153c8..3f2a400dba3 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToOne.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/RequestHandlerOneToOne.java @@ -52,7 +52,11 @@ public JsonRpcResult handle(String endpointId, JsonRpcParams params) throws Json LOG.debug("Handling request from: {}, with params: {}", endpointId, params); - P paramsObject = params.getAs(pClass); + P paramsObject = pClass.equals(String.class) || + pClass.equals(Boolean.class) || + pClass.equals(Double.class) ? params.getAsListOf(pClass).get(0) + : params.getAs(pClass); + LOG.debug("Created raw params object: {}", paramsObject); R result = function.apply(endpointId, paramsObject); LOG.debug("Received result: {}", result); diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/transmission/SendConfiguratorFromMany.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/transmission/SendConfiguratorFromMany.java index 3a1df1b2fff..b49a4308bde 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/transmission/SendConfiguratorFromMany.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/transmission/SendConfiguratorFromMany.java @@ -167,7 +167,7 @@ public JsonRpcPromise sendAndReceiveResultAsEmpty() { } private void transmitNotification() { - JsonRpcParams params = factory.createParamsList(pListValue); + JsonRpcParams params = factory.createParams(pListValue); JsonRpcRequest request = factory.createRequest(method, params); transmitter.transmit(endpointId, request.toString()); } @@ -176,7 +176,7 @@ private String transmitRequest() { Integer id = MethodNameConfigurator.id.incrementAndGet(); String requestId = id.toString(); - JsonRpcParams params = factory.createParamsList(pListValue); + JsonRpcParams params = factory.createParams(pListValue); JsonRpcRequest request = factory.createRequest(requestId, method, params); transmitter.transmit(endpointId, request.toString()); return requestId; diff --git a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParamsTest.java b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParamsTest.java index fac74cb1ff5..d9a0f45683a 100644 --- a/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParamsTest.java +++ b/core/che-core-api-core/src/test/java/org/eclipse/che/api/core/jsonrpc/JsonRpcParamsTest.java @@ -168,13 +168,12 @@ public void shouldToJsonForCreatedListStringParams() throws Exception { JsonArray expected = new JsonArray(); expected.add(new JsonPrimitive(value)); - JsonRpcParams jsonRpcParams = new JsonRpcParams(singletonList(value), jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, singletonList(value)); JsonElement actual = jsonRpcParams.toJsonElement(); assertEquals(expected, actual); } - @Test public void shouldToStringCreatedListStringParams() throws Exception { String value = "value"; @@ -182,7 +181,7 @@ public void shouldToStringCreatedListStringParams() throws Exception { array.add(new JsonPrimitive(value)); String expected = array.toString(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(singletonList(value), jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, singletonList(value)); String actual = jsonRpcParams.toString(); assertEquals(expected, actual); @@ -225,7 +224,7 @@ public void shouldGetAsListForParsedListDoubleParams() throws Exception { JsonRpcParams jsonRpcParams = new JsonRpcParams("[\"" + expected + "\"]", jsonParser); List actual = jsonRpcParams.getAsListOf(Double.class); - assertEquals(singletonList(expected), actual); + assertEquals(singletonList(expected).toString(), actual.toString()); } @Test @@ -257,7 +256,7 @@ public void shouldToStringForParsedListDoubleParams() throws Exception { public void shouldGetAsForCreatedSingleDoubleParams() throws Exception { Double expected = 0D; - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, expected); Double actual = jsonRpcParams.getAs(Double.class); assertEquals(expected, actual); @@ -267,7 +266,7 @@ public void shouldGetAsForCreatedSingleDoubleParams() throws Exception { public void shouldToJsonForCreatedSingleDoubleParams() throws Exception { Double expected = 0D; - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, expected); JsonElement actual = jsonRpcParams.toJsonElement(); assertEquals(expected, Double.valueOf(actual.toString())); @@ -277,7 +276,7 @@ public void shouldToJsonForCreatedSingleDoubleParams() throws Exception { public void shouldToStringCreatedSingleDoubleParams() throws Exception { Double expected = 0D; - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, expected); String actual = jsonRpcParams.toString(); assertEquals(expected, Double.valueOf(actual)); @@ -290,7 +289,7 @@ public void shouldToJsonForCreatedListDoubleParams() throws Exception { JsonArray expected = new JsonArray(); expected.add(new JsonPrimitive(value)); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, list); JsonElement actual = jsonRpcParams.toJsonElement(); assertEquals(expected, actual); @@ -305,7 +304,7 @@ public void shouldToStringCreatedListDoubleParams() throws Exception { jsonArray.add(new JsonPrimitive(value)); String expected = jsonArray.toString(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, list); String actual = jsonRpcParams.toString(); assertEquals(expected, actual); @@ -390,7 +389,7 @@ public void shouldGetAsForCreatedSingleBooleanParams() throws Exception { public void shouldToJsonForCreatedSingleBooleanParams() throws Exception { Boolean expected = false; - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, expected); JsonElement actual = jsonRpcParams.toJsonElement(); assertEquals(expected, Boolean.valueOf(actual.toString())); @@ -400,7 +399,7 @@ public void shouldToJsonForCreatedSingleBooleanParams() throws Exception { public void shouldToStringCreatedSingleBooleanParams() throws Exception { Boolean expected = false; - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, expected); String actual = jsonRpcParams.toString(); assertEquals(expected, Boolean.valueOf(actual)); @@ -413,7 +412,7 @@ public void shouldToJsonForCreatedListBooleanParams() throws Exception { JsonArray expected = new JsonArray(); expected.add(new JsonPrimitive(value)); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, list); JsonElement actual = jsonRpcParams.toJsonElement(); assertEquals(expected, actual); @@ -427,7 +426,7 @@ public void shouldToStringCreatedListBooleanParams() throws Exception { jsonArray.add(new JsonPrimitive(value)); String expected = jsonArray.toString(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, list); String actual = jsonRpcParams.toString(); assertEquals(expected, actual); @@ -481,7 +480,7 @@ public void shouldToStringForParsedListDtoParams() throws Exception { @Test public void shouldToJsonForCreatedSingleDtoParams() throws Exception { JsonObject expected = jsonParser.parse(dto.toString()).getAsJsonObject(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(dto, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, dto); JsonElement actual = jsonRpcParams.toJsonElement(); assertEquals(expected, actual); @@ -491,7 +490,7 @@ public void shouldToJsonForCreatedSingleDtoParams() throws Exception { public void shouldToStringCreatedSingleDtoParams() throws Exception { String expected = jsonParser.parse(dto.toString()).toString(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(dto, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, dto); String actual = jsonRpcParams.toString(); assertEquals(expected, actual); @@ -505,7 +504,7 @@ public void shouldToJsonForCreatedListDtoParams() throws Exception { JsonElement element = jsonParser.parse(dto.toString()); expected.add(element); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, list); JsonElement actual = jsonRpcParams.toJsonElement(); assertEquals(expected, actual); @@ -520,7 +519,7 @@ public void shouldToStringCreatedListDtoParams() throws Exception { jsonArray.add(jsonValue); String expected = jsonArray.toString(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, list); String actual = jsonRpcParams.toString(); assertEquals(expected, actual); @@ -571,21 +570,21 @@ public void shouldNotBeEmptyOrAbsentForStringCreatedParams() throws Exception { @Test public void shouldNotBeEmptyOrAbsentForBooleanCreatedParams() throws Exception { - JsonRpcParams jsonRpcParams = new JsonRpcParams(false, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, false); assertFalse(jsonRpcParams.emptyOrAbsent()); } @Test public void shouldNotBeEmptyOrAbsentForNumberCreatedParams() throws Exception { - JsonRpcParams jsonRpcParams = new JsonRpcParams(0D, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, 0D); assertFalse(jsonRpcParams.emptyOrAbsent()); } @Test public void shouldNotBeEmptyOrAbsentForDtoCreatedParams() throws Exception { - JsonRpcParams jsonRpcParams = new JsonRpcParams(dto, jsonParser); + JsonRpcParams jsonRpcParams = new JsonRpcParams(jsonParser, dto); assertFalse(jsonRpcParams.emptyOrAbsent()); } diff --git a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcFactory.java b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcFactory.java index 12e77e44d74..1a02eb05231 100644 --- a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcFactory.java +++ b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcFactory.java @@ -175,15 +175,4 @@ JsonRpcResponse createResponse(@Assisted("id") String id, @Assisted("result") Js * @return JSON RPC params */ JsonRpcParams createParams(@Assisted("params") Object params); - - /** - * Create a JSON RPC params instance by passing corresponding values. - * Params should be represented by a list of objects. - * - * @param params - * params list - * - * @return JSON RPC params - */ - JsonRpcParams createParamsList(@Assisted("params") List params); } diff --git a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcParams.java b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcParams.java index d0d6a4e12de..130cd40c79c 100644 --- a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcParams.java +++ b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/JsonRpcParams.java @@ -10,9 +10,9 @@ *******************************************************************************/ package org.eclipse.che.ide.jsonrpc; -import elemental.json.Json; import elemental.json.JsonArray; import elemental.json.JsonFactory; +import elemental.json.JsonObject; import elemental.json.JsonType; import elemental.json.JsonValue; @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -35,15 +36,11 @@ * {@link JsonRpcFactory#createParams(String)} to get an instance. */ public class JsonRpcParams { - private static final JsonValue EMPTY_OBJECT = Json.instance().parse("{}"); - private static final JsonValue EMPTY_ARRAY = Json.instance().parse("[]"); - private final JsonFactory jsonFactory; private final DtoFactory dtoFactory; - private List paramsList; - private List stringParamsList; - private JsonValue params; + private List> params; + private Param param; @AssistedInject public JsonRpcParams(@Assisted("message") String message, JsonFactory jsonFactory, DtoFactory dtoFactory) { @@ -56,18 +53,37 @@ public JsonRpcParams(@Assisted("message") String message, JsonFactory jsonFactor JsonValue jsonValue = jsonFactory.parse(message); if (jsonValue.getType().equals(JsonType.ARRAY)) { JsonArray jsonArray = jsonFactory.parse(message); - this.paramsList = new ArrayList<>(jsonArray.length()); - this.stringParamsList = new ArrayList<>(jsonArray.length()); + this.params = new ArrayList<>(jsonArray.length()); for (int i = 0; i < jsonArray.length(); i++) { JsonValue element = jsonArray.get(i); + Param paramCandidate; if (element.getType().equals(JsonType.STRING)) { - this.stringParamsList.add(element.asString()); + paramCandidate = new Param<>(String.class, element.asString()); + } else if (element.getType().equals(JsonType.BOOLEAN)) { + paramCandidate = new Param<>(Boolean.class, element.asBoolean()); + } else if (element.getType().equals(JsonType.NUMBER)) { + paramCandidate = new Param<>(Double.class, element.asNumber()); } else { - this.paramsList.add(i, element); + paramCandidate = new Param<>(Object.class, element); } + this.params.add(paramCandidate); } + this.param = null; + } else if (jsonValue.getType().equals(JsonType.STRING)) { + this.param = new Param<>(String.class, jsonValue.asString()); + this.params = null; + } else if (jsonValue.getType().equals(JsonType.BOOLEAN)) { + this.param = new Param<>(Boolean.class, jsonValue.asBoolean()); + this.params = null; + } else if (jsonValue.getType().equals(JsonType.NUMBER)) { + this.param = new Param<>(Double.class, jsonValue.asNumber()); + this.params = null; + } else if (jsonValue.getType().equals(JsonType.OBJECT)) { + this.param = new Param<>(Object.class, jsonValue); + this.params = null; } else { - this.params = jsonFactory.parse(message); + this.param = null; + this.params = null; } } @@ -76,116 +92,115 @@ public JsonRpcParams(@Assisted("params") Object params, DtoFactory dtoFactory, J this.jsonFactory = jsonFactory; this.dtoFactory = dtoFactory; - if (params instanceof String) { - this.params = jsonFactory.create((String)params); - } else if (params instanceof Double) { - this.params = jsonFactory.create((Double)params); - } else if (params instanceof Boolean) { - this.params = jsonFactory.create((Boolean)params); - } else if (params == null) { - this.params = jsonFactory.createObject(); + if (params == null) { + this.param = null; + this.params = null; } else { - this.params = jsonFactory.parse(params.toString()); - } - } - - @AssistedInject - public JsonRpcParams(@Assisted("params") List params, JsonFactory jsonFactory, DtoFactory dtoFactory) { - checkNotNull(params, "Params must not be null"); - checkArgument(!params.isEmpty(), "Params must not be empty"); - - this.jsonFactory = jsonFactory; - this.dtoFactory = dtoFactory; - - this.paramsList = new ArrayList<>(params.size()); - this.stringParamsList = new ArrayList<>(params.size()); + if (params instanceof List) { + List listParams = (List)params; + this.params = new ArrayList<>(listParams.size()); + + for (Object param : listParams) { + Param paramCandidate; + if (param instanceof String) { + paramCandidate = new Param<>(String.class, (String)param); + } else if (param instanceof Double) { + paramCandidate = new Param<>(Double.class, (Double)param); + } else if (param instanceof Boolean) { + paramCandidate = new Param<>(Boolean.class, (Boolean)param); + } else { + paramCandidate = new Param<>(Object.class, param); + } + this.params.add(paramCandidate); + } - for (int i = 0; i < params.size(); i++) { - Object item = params.get(i); - if (item instanceof String) { -// paramsList.add(i, jsonFactory.create((String)item)); - this.stringParamsList.add((String)item); - } else if (item instanceof Double) { - paramsList.add(i, jsonFactory.create((Double)item)); - } else if (item instanceof Boolean) { - paramsList.add(i, jsonFactory.create((Boolean)item)); + this.param = null; } else { - paramsList.add(i, jsonFactory.parse(item.toString())); + if (params instanceof String) { + this.param = new Param<>(String.class, (String)params); + } else if (params instanceof Double) { + this.param = new Param<>(Double.class, (Double)params); + } else if (params instanceof Boolean) { + this.param = new Param<>(Boolean.class, (Boolean)params); + } else { + this.param = new Param<>(Object.class, params); + } + + this.params = null; } } } + @SuppressWarnings("unchecked") + static T cast(Object object) { + return (T)object; + } + public boolean emptyOrAbsent() { - return (paramsList == null || EMPTY_ARRAY.jsEquals(toJsonValue())) && (params == null || EMPTY_OBJECT.jsEquals(toJsonValue())); + return (params == null || params.isEmpty()) && + (param == null || (param.value instanceof JsonObject && jsonFactory.createObject().jsEquals((JsonObject)param.value))); } public JsonValue toJsonValue() { - if (params != null) { - return params; - } else { - JsonArray array = jsonFactory.createArray(); - for (int i = 0; i < stringParamsList.size(); i++) { - String value = stringParamsList.get(i); - array.set(i, value); + if (param != null) { + if (param.type.equals(String.class)) { + return jsonFactory.create((String)param.value); + } else if (param.type.equals(Boolean.class)) { + return jsonFactory.create((Boolean)param.value); + } else if (param.type.equals(Double.class)) { + return jsonFactory.create((Double)param.value); + } else { + return jsonFactory.parse(param.value.toString()); } - for (int i = 0; i < paramsList.size(); i++) { - JsonValue value = paramsList.get(i); - array.set(i, value); + } + + JsonArray array = jsonFactory.createArray(); + for (int i = 0; i < params.size(); i++) { + Param paramCandidate = params.get(i); + JsonValue jsonValue; + if (paramCandidate.type.equals(String.class)) { + jsonValue = jsonFactory.create((String)paramCandidate.value); + } else if (paramCandidate.type.equals(Boolean.class)) { + jsonValue = jsonFactory.create((Boolean)paramCandidate.value); + } else if (paramCandidate.type.equals(Double.class)) { + jsonValue = jsonFactory.create((Double)paramCandidate.value); + } else { + jsonValue = jsonFactory.parse(paramCandidate.value.toString()); } - return array; + + array.set(i, jsonValue); } + + return array; } public T getAs(Class type) { - checkNotNull(params, "Type must not be null"); - - if (type.equals(String.class)) { - String s = params.asString(); - return (T)s; - } else if (type.equals(Double.class)) { - Double d = params.asNumber(); - return (T)d; - } else if (type.equals(Boolean.class)) { - Boolean b = params.asBoolean(); - return (T)b; - } else if (type.equals(Void.class)) { - return (T)null; - } else { - return dtoFactory.createDtoFromJson(params.toJson(), type); - } + checkNotNull(param, "Type must not be null"); + + return param.type.equals(Object.class) + ? dtoFactory.createDtoFromJson(param.value.toString(), type) + : cast(param.value); + } public List getAsListOf(Class type) { checkNotNull(type, "Type must not be null"); - if (type.equals(String.class)){ - return (List)stringParamsList; - } - - List list = new ArrayList<>(paramsList.size()); - - for (int i = 0; i < paramsList.size(); i++) { - JsonValue jsonValue = paramsList.get(i); - T item; - if (type.equals(String.class)) { - item = (T)jsonValue.asString(); - } else if (type.equals(Double.class)) { - Double d = jsonValue.asNumber(); - item = (T)d; - } else if (type.equals(Boolean.class)) { - Boolean b = jsonValue.asBoolean(); - item = (T)b; - } else { - item = dtoFactory.createDtoFromJson(jsonValue.toJson(), type); - } - list.add(i, item); - } - - return list; + return params.stream().map(it -> it.value).collect(cast(Collectors.toList())); } @Override public String toString() { return toJsonValue().toJson(); } + + private class Param { + final private Class type; + final private T value; + + private Param(Class type, T value) { + this.type = type; + this.value = value; + } + } } diff --git a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToList.java b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToList.java index 3e4c2dba548..de31d4da9e7 100644 --- a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToList.java +++ b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToList.java @@ -49,7 +49,11 @@ public JsonRpcResult handle(String endpointId, JsonRpcParams params) throws Json Log.debug(getClass(), "Handling request from: " + endpointId + ", with params: " + params); - P paramsObject = params.getAs(pClass); + P paramsObject = pClass.equals(String.class) || + pClass.equals(Boolean.class) || + pClass.equals(Double.class) ? params.getAsListOf(pClass).get(0) + : params.getAs(pClass); + Log.debug(getClass(), "Created raw params object: " + paramsObject); List resultList = biFunction.apply(endpointId, paramsObject); Log.debug(getClass(), "Received result list: " + resultList); diff --git a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToOne.java b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToOne.java index 057f56d7cf4..24eea6d0478 100644 --- a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToOne.java +++ b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/RequestHandlerOneToOne.java @@ -47,7 +47,11 @@ public JsonRpcResult handle(String endpointId, JsonRpcParams params) throws Json Log.debug(getClass(), "Handling request from: " + endpointId + ", with params: " + params); - P paramsObject = params.getAs(pClass); + P paramsObject = pClass.equals(String.class) || + pClass.equals(Boolean.class) || + pClass.equals(Double.class) ? params.getAsListOf(pClass).get(0) + : params.getAs(pClass); + Log.debug(getClass(), "Created raw params object: " + paramsObject); R result = biFunction.apply(endpointId, paramsObject); Log.debug(getClass(), "Received result: " + result); diff --git a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/transmission/SendConfiguratorFromList.java b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/transmission/SendConfiguratorFromList.java index 7e60f2d41bf..168726d0ef5 100644 --- a/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/transmission/SendConfiguratorFromList.java +++ b/ide/commons-gwt/src/main/java/org/eclipse/che/ide/jsonrpc/transmission/SendConfiguratorFromList.java @@ -201,15 +201,14 @@ public void apply(ResolveFunction resolve, RejectFunction reject) { } private void transmitNotification() { - JsonRpcParams params = factory.createParamsList(pListValue); + JsonRpcParams params = factory.createParams(pListValue); JsonRpcRequest request = factory.createRequest(method, params); transmitter.transmit(endpointId, request.toString()); } private String transmitRequest() { + JsonRpcParams params = factory.createParams(pListValue); String requestId = Integer.valueOf(MethodNameConfigurator.id.incrementAndGet()).toString(); - - JsonRpcParams params = factory.createParamsList(pListValue); JsonRpcRequest request = factory.createRequest(requestId, method, params); transmitter.transmit(endpointId, request.toString()); return requestId; diff --git a/ide/commons-gwt/src/test/java/org/eclipse/che/ide/jsonrpc/JsonRpcParamsTest.java b/ide/commons-gwt/src/test/java/org/eclipse/che/ide/jsonrpc/JsonRpcParamsTest.java index 466ef5c7820..a1d6ba14b8f 100644 --- a/ide/commons-gwt/src/test/java/org/eclipse/che/ide/jsonrpc/JsonRpcParamsTest.java +++ b/ide/commons-gwt/src/test/java/org/eclipse/che/ide/jsonrpc/JsonRpcParamsTest.java @@ -157,7 +157,7 @@ public void shouldToStringCreatedSingleStringParams() throws Exception { public void shouldGetAsListForCreatedListStringParams() throws Exception { List expected = singletonList("value"); - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, dtoFactory, jsonFactory); List actual = jsonRpcParams.getAsListOf(String.class); assertEquals(expected, actual); @@ -169,7 +169,7 @@ public void shouldToJsonForCreatedListStringParams() throws Exception { JsonArray expected = jsonFactory.createArray(); expected.set(0, value); - JsonRpcParams jsonRpcParams = new JsonRpcParams(singletonList(value), jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(singletonList(value), dtoFactory, jsonFactory); JsonValue actual = jsonRpcParams.toJsonValue(); assertTrue(expected.jsEquals(actual)); @@ -182,7 +182,7 @@ public void shouldToStringCreatedListStringParams() throws Exception { JsonArray expected = jsonFactory.createArray(); expected.set(0, value); - JsonRpcParams jsonRpcParams = new JsonRpcParams(singletonList(value), jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(singletonList(value), dtoFactory, jsonFactory); String actual = jsonRpcParams.toString(); assertEquals(expected.toJson(), actual); @@ -225,7 +225,7 @@ public void shouldGetAsListForParsedListDoubleParams() throws Exception { JsonRpcParams jsonRpcParams = new JsonRpcParams("[" + expected + "]", jsonFactory, dtoFactory); List actual = jsonRpcParams.getAsListOf(Double.class); - assertEquals(singletonList(expected), actual); + assertEquals(singletonList(expected).toString(), actual.toString()); } @Test @@ -287,7 +287,7 @@ public void shouldToStringCreatedSingleDoubleParams() throws Exception { public void shouldGetAsListForCreatedListDoubleParams() throws Exception { List expected = singletonList(0D); - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, dtoFactory, jsonFactory); List actual = jsonRpcParams.getAsListOf(Double.class); assertEquals(expected, actual); @@ -300,7 +300,7 @@ public void shouldToJsonForCreatedListDoubleParams() throws Exception { JsonArray expected = jsonFactory.createArray(); expected.set(0, value); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(list, dtoFactory, jsonFactory); JsonValue actual = jsonRpcParams.toJsonValue(); assertTrue(expected.jsEquals(actual)); @@ -315,7 +315,7 @@ public void shouldToStringCreatedListDoubleParams() throws Exception { jsonArray.set(0, value); String expected = jsonArray.toJson(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(list, dtoFactory, jsonFactory); String actual = jsonRpcParams.toString(); assertEquals(expected, actual); @@ -420,7 +420,7 @@ public void shouldToStringCreatedSingleBooleanParams() throws Exception { public void shouldGetAsListForCreatedListBooleanParams() throws Exception { List expected = singletonList(false); - JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(expected, dtoFactory, jsonFactory); List actual = jsonRpcParams.getAsListOf(Boolean.class); assertEquals(expected, actual); @@ -433,7 +433,7 @@ public void shouldToJsonForCreatedListBooleanParams() throws Exception { JsonArray expected = jsonFactory.createArray(); expected.set(0, value); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(list, dtoFactory, jsonFactory); JsonValue actual = jsonRpcParams.toJsonValue(); assertTrue(expected.jsEquals(actual)); @@ -447,7 +447,7 @@ public void shouldToStringCreatedListBooleanParams() throws Exception { jsonArray.set(0, value); String expected = jsonArray.toJson(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(list, dtoFactory, jsonFactory); String actual = jsonRpcParams.toString(); assertEquals(expected, actual); @@ -457,7 +457,7 @@ public void shouldToStringCreatedListBooleanParams() throws Exception { public void shouldGetAsForParsedSingleDtoParams() throws Exception { String expected = DTO_JSON; - JsonRpcParams jsonRpcParams = new JsonRpcParams(DTO_JSON, dtoFactory, jsonFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(DTO_JSON, jsonFactory, dtoFactory); String actual = jsonRpcParams.getAs(Dto.class).toString(); assertEquals(expected, actual); @@ -487,8 +487,9 @@ public void shouldToStringForParsedSingleDtoParams() throws Exception { public void shouldGetAsListForParsedListDtoParams() throws Exception { JsonRpcParams jsonRpcParams = new JsonRpcParams("[" + DTO_JSON + "]", jsonFactory, dtoFactory); List actual = jsonRpcParams.getAsListOf(Dto.class); + List expected = singletonList(dto); - assertEquals(singletonList(dto), actual); + assertEquals(expected.toString(), actual.toString()); } @Test @@ -548,7 +549,7 @@ public void shouldToStringCreatedSingleDtoParams() throws Exception { public void shouldGetAsListForCreatedListDtoParams() throws Exception { List list = singletonList(dto); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(list, dtoFactory, jsonFactory); List actual = jsonRpcParams.getAsListOf(Dto.class); assertEquals(list, actual); @@ -562,7 +563,7 @@ public void shouldToJsonForCreatedListDtoParams() throws Exception { JsonValue jsonValue = jsonFactory.parse(dto.toString()); expected.set(0, jsonValue); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(list, dtoFactory, jsonFactory); JsonValue actual = jsonRpcParams.toJsonValue(); assertTrue(expected.jsEquals(actual)); @@ -577,7 +578,7 @@ public void shouldToStringCreatedListDtoParams() throws Exception { jsonArray.set(0, jsonValue); String expected = jsonArray.toJson(); - JsonRpcParams jsonRpcParams = new JsonRpcParams(list, jsonFactory, dtoFactory); + JsonRpcParams jsonRpcParams = new JsonRpcParams(list, dtoFactory, jsonFactory); String actual = jsonRpcParams.toString(); assertEquals(expected, actual);