Skip to content

Commit

Permalink
Wrap primitive and array parameter into an array as in JSON-RPC 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dhuebner committed Mar 15, 2023
1 parent 9071352 commit 21cb96a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

Expand Down Expand Up @@ -42,6 +43,7 @@
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.Primitives;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
Expand Down Expand Up @@ -266,12 +268,19 @@ protected Object parseParams(JsonReader in, String method) throws IOException, J
List<Object> parameters = new ArrayList<Object>(parameterTypes.length);
int index = 0;
in.beginArray();
boolean wrappedArray = in.peek() == JsonToken.BEGIN_ARRAY;
if(wrappedArray) {
in.beginArray();
}
while (in.hasNext()) {
Type parameterType = index < parameterTypes.length ? parameterTypes[index] : null;
Object parameter = fromJson(in, parameterType);
parameters.add(parameter);
index++;
}
if(wrappedArray) {
in.endArray();
}
in.endArray();
while (index < parameterTypes.length) {
parameters.add(null);
Expand Down Expand Up @@ -420,7 +429,7 @@ public void write(JsonWriter out, Message message) throws IOException {
if (params == null)
writeNullValue(out);
else
gson.toJson(params, params.getClass(), out);
handleParameter(out, params);
} else if (message instanceof ResponseMessage) {
ResponseMessage responseMessage = (ResponseMessage) message;
out.name("id");
Expand All @@ -445,12 +454,24 @@ public void write(JsonWriter out, Message message) throws IOException {
if (params == null)
writeNullValue(out);
else
gson.toJson(params, params.getClass(), out);
handleParameter(out, params);
}

out.endObject();
}

protected void handleParameter(JsonWriter out, Object params) {
if(Collection.class.isInstance(params)
|| params.getClass().isArray()
|| params instanceof String
|| Primitives.isPrimitive(getClass())
|| Primitives.isWrapperType(params.getClass())) {
gson.toJson(List.of(params), List.class, out);
} else {
gson.toJson(params, params.getClass(), out);
}
}

protected void writeId(JsonWriter out, Either<String, Number> id) throws IOException {
if (id == null)
writeNullValue(out);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void testSerializeEmptyList() {
message.setMethod("foo");
message.setParams(Collections.EMPTY_LIST);
String json = handler.serialize(message);
Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"method\":\"foo\",\"params\":[]}", json);
Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"method\":\"foo\",\"params\":[[]]}", json);
}

@Test
Expand All @@ -151,7 +151,7 @@ public void testSerializeImmutableList() {
list.add("b");
message.setParams(Collections.unmodifiableList(list));
String json = handler.serialize(message);
Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"method\":\"foo\",\"params\":[\"a\",\"b\"]}", json);
Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"method\":\"foo\",\"params\":[[\"a\",\"b\"]]}", json);
}

@SuppressWarnings({ "unchecked" })
Expand Down Expand Up @@ -437,7 +437,7 @@ public void testRawMultiParamsParsing_03() {
RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+ "\"id\":\"2\",\n"
+ "\"method\":\"foo\",\n"
+ "\"params\": [[\"foo\", \"bar\"], [1, 2], {\"uri\": \"dummy://mymodel.mydsl\"}]\n"
+ "\"params\": [[[\"foo\", \"bar\"], [1, 2], {\"uri\": \"dummy://mymodel.mydsl\"}]]\n"
+ "}");
Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);

Expand All @@ -462,7 +462,7 @@ public void testRawMultiParamsParsing_04() {
RequestMessage message = (RequestMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+ "\"id\":\"2\",\n"
+ "\"method\":\"foo\",\n"
+ "\"params\": [[\"foo\", \"bar\"], [1, 2]]\n"
+ "\"params\": [[[\"foo\", \"bar\"], [1, 2]]]\n"
+ "}");
Assert.assertTrue("" + message.getParams().getClass(), message.getParams() instanceof List);

Expand Down Expand Up @@ -792,13 +792,41 @@ public void testParamUnwrap_JsonRpc2_0() {
var request = new RequestMessage();
request.setId(1);
request.setMethod(handler.getMethodProvider().resolveMethod(null));
request.setParams(new boolean[] { true }); // fake wrapped primitive [true] for JsonRpc 2.0
request.setParams(true); // fake wrapped primitive [true] for JsonRpc 2.0

RequestMessage message = (RequestMessage) handler.parseMessage(request.toString());

// Check parse - unwrap primitive
assertEquals(true, message.getParams());
}

@Test
public void testParamWrap_JsonRpc2_0() {
MessageJsonHandler handler = createSimpleRequestHandler(String.class, Boolean.class);

var request = new RequestMessage();
request.setMethod(handler.getMethodProvider().resolveMethod(null));
request.setParams(true);

// Check serialize - wrap primitive
assertEquals("{\"jsonrpc\":\"2.0\",\"id\":null,\"method\":\"testMethod\",\"params\":[true]}", handler.serialize(request));

request.setParams(Boolean.TRUE);
// Check serialize - wrap primitive wrapper
assertEquals("{\"jsonrpc\":\"2.0\",\"id\":null,\"method\":\"testMethod\",\"params\":[true]}", handler.serialize(request));
}

@Test
public void testParamWrapString_JsonRpc2_0() {
MessageJsonHandler handler = createSimpleRequestHandler(String.class, String.class);

var request = new RequestMessage();
request.setMethod(handler.getMethodProvider().resolveMethod(null));
request.setParams("some string");

// Check serialize - wrap primitive
assertEquals("{\"jsonrpc\":\"2.0\",\"id\":null,\"method\":\"testMethod\",\"params\":[\"some string\"]}",
handler.serialize(request));
}

@Test
Expand All @@ -818,6 +846,23 @@ public void testArrayParamUnwrap_JsonRpc2_0() {

}

@Test
public void testArrayParamWrap_JsonRpc2_0() {
MessageJsonHandler handler = createSimpleRequestHandler(String.class, new TypeToken<List<Boolean>>() {
}.getType());

var request = new RequestMessage();
request.setMethod(handler.getMethodProvider().resolveMethod(null));
request.setParams(new Boolean[] { true, false });
// Check serialize - wrap primitive wrapper
assertEquals("{\"jsonrpc\":\"2.0\",\"id\":null,\"method\":\"testMethod\",\"params\":[[true,false]]}",
handler.serialize(request));
request.setParams(List.of(true, false));
// Check serialize - wrap primitive wrapper
assertEquals("{\"jsonrpc\":\"2.0\",\"id\":null,\"method\":\"testMethod\",\"params\":[[true,false]]}",
handler.serialize(request));
}

@Test
public void testMultiParamUnwrap_JsonRpc2_0() {
MessageJsonHandler handler = createSimpleRequestHandler(String.class, Boolean.class, String.class);
Expand Down

0 comments on commit 21cb96a

Please sign in to comment.