@SuppressWarnings({ "unchecked" }) @Test public void testParseList() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<List<? extends Entry>>() {}.getType(), new TypeToken<List<? extends Entry>>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id)->"foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + " \"body\": [\n" + " {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n" + " {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n" + " {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n" + " {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n" + " {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n" + "]}"); List<? extends Entry> result = (List<? extends Entry>) ((ResponseMessage)message).getResult(); Assert.assertEquals(5, result.size()); for (Entry e : result) { Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria")); } }
@SuppressWarnings({ "unchecked" }) @Test public void testParseList_02() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Set<Entry>>() {}.getType(), new TypeToken<Set<Entry>>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id)->"foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + " \"body\": [\n" + " {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n" + " {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n" + " {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n" + " {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n" + " {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n" + "]}"); Set<Entry> result = (Set<Entry>) ((ResponseMessage)message).getResult(); Assert.assertEquals(5, result.size()); for (Entry e : result) { Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria")); } }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_02() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<MyEnum, Map<String,String>>>() {}.getType(), new TypeToken<Object>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": 2\n" + "}"); Either<MyEnum, List<Map<String, String>>> result = (Either<MyEnum, List<Map<String,String>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertEquals(MyEnum.B, result.getLeft()); }
@Override public void consume(Message message) { List<String> result = new ArrayList<>(); try { validate(message, result, new LinkedList<>()); } catch (Throwable e) { LOG.log(Level.SEVERE, "Error during message validation: " + e.getMessage(), e); result.add("The message validation failed, please look at the server's logs."); } if (!result.isEmpty()) { ResponseError error = new ResponseError(ResponseErrorCode.InvalidParams, result.stream().collect(Collectors.joining(", ")), message); throw new InvalidMessageException(error.getMessage(), error, null); } else if (delegate != null) { delegate.consume(message); } }
@Override public void consume(Message message) { if (message.getJsonrpc() == null) { message.setJsonrpc(JSONRPC_VERSION); } try { String content = jsonHandler.serialize(message); byte[] contentBytes = content.getBytes(encoding); int contentLength = contentBytes.length; String header = getHeader(contentLength); byte[] headerBytes = header.getBytes(StandardCharsets.US_ASCII); synchronized (outputLock) { output.write(headerBytes); output.write(contentBytes); output.flush(); } } catch (IOException e) { throw new RuntimeException(e); } }
protected boolean handleMessage(InputStream input, Headers headers) throws IOException { try { int contentLength = headers.contentLength; byte[] buffer = new byte[contentLength]; int bytesRead = 0; while (bytesRead < contentLength) { int readResult = input.read(buffer, bytesRead, contentLength - bytesRead); if (readResult == -1) return false; bytesRead += readResult; } String content = new String(buffer, headers.charset); Message message = jsonHandler.parseMessage(content); callback.consume(message); } catch (UnsupportedEncodingException | InvalidMessageException e) { fireError(e); } return true; }
@Test public void testNullResponse() throws InterruptedException, ExecutionException { Endpoint endpoint = ServiceEndpoints.toEndpoint(this); Map<String, JsonRpcMethod> methods = ServiceEndpoints.getSupportedMethods(LanguageServer.class); MessageJsonHandler handler = new MessageJsonHandler(methods); List<Message> msgs = new ArrayList<>(); MessageConsumer consumer = (message) -> { msgs.add(message); }; RemoteEndpoint re = new RemoteEndpoint(consumer, endpoint); RequestMessage request = new RequestMessage(); request.setId("1"); request.setMethod("shutdown"); re.consume(request); Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"result\":null}", handler.serialize(msgs.get(0))); msgs.clear(); shutdownReturn = new Object(); re.consume(request); Assert.assertEquals("{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"result\":{}}", handler.serialize(msgs.get(0))); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_02() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<Integer, Map<String,String>>>() {}.getType(), new TypeToken<Object>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": 2\n" + "}"); Either<Integer, List<Map<String, String>>> result = (Either<Integer, List<Map<String,String>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertEquals(Integer.valueOf(2), result.getLeft()); }
@SuppressWarnings({ "unchecked" }) @Test public void testParseList() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<List<? extends Entry>>() {}.getType(), new TypeToken<List<? extends Entry>>() {}.getType())); MessageJsonHandler handler = new MessageJsonHandler(supportedMethods); handler.setMethodProvider((id)->"foo"); Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + " \"result\": [\n" + " {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n" + " {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n" + " {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n" + " {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n" + " {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n" + "]}"); List<? extends Entry> result = (List<? extends Entry>) ((ResponseMessage)message).getResult(); Assert.assertEquals(5, result.size()); for (Entry e : result) { Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria")); } }
@SuppressWarnings({ "unchecked" }) @Test public void testParseList_02() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Set<Entry>>() {}.getType(), new TypeToken<Set<Entry>>() {}.getType())); MessageJsonHandler handler = new MessageJsonHandler(supportedMethods); handler.setMethodProvider((id)->"foo"); Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + " \"result\": [\n" + " {\"name\":\"$schema\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":1,\"character\":3},\"end\":{\"line\":1,\"character\":55}}}},\n" + " {\"name\":\"type\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":2,\"character\":3},\"end\":{\"line\":2,\"character\":19}}}},\n" + " {\"name\":\"title\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":3,\"character\":3},\"end\":{\"line\":3,\"character\":50}}}},\n" + " {\"name\":\"additionalProperties\",\"kind\":17,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":4,\"character\":4},\"end\":{\"line\":4,\"character\":32}}}},\n" + " {\"name\":\"properties\",\"kind\":15,\"location\":{\"uri\":\"file:/home/mistria/runtime-EclipseApplication-with-patch/EclipseConEurope/something.json\",\"range\":{\"start\":{\"line\":5,\"character\":3},\"end\":{\"line\":5,\"character\":20}}}}\n" + "]}"); Set<Entry> result = (Set<Entry>) ((ResponseMessage)message).getResult(); Assert.assertEquals(5, result.size()); for (Entry e : result) { Assert.assertTrue(e.location.uri, e.location.uri.startsWith("file:/home/mistria")); } }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_02() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<MyEnum, Map<String,String>>>() {}.getType(), new TypeToken<Object>() {}.getType())); MessageJsonHandler handler = new MessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + "\"result\": 2\n" + "}"); Either<MyEnum, List<Map<String, String>>> result = (Either<MyEnum, List<Map<String,String>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertEquals(MyEnum.B, result.getLeft()); }
@Override @SuppressWarnings("unchecked") public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { if (!Message.class.isAssignableFrom(typeToken.getRawType())) return null; return (TypeAdapter<T>) new Adapter(handler, gson); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_01() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<String, List<Map<String,String>>>>() {}.getType(), new TypeToken<Either<String, Integer>>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + " \"body\": [\n" + " {\"name\":\"foo\"},\n" + " {\"name\":\"bar\"}\n" + "]}"); Either<String, List<Map<String, String>>> result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); for (Map<String, String> e : result.getRight()) { Assert.assertNotNull(e.get("name")); } message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": \"name\"\n" + "}"); result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult(); Assert.assertFalse(result.isRight()); Assert.assertEquals("name",result.getLeft()); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_04() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<MyClass, List<? extends MyClass>>>() {}.getType(), new TypeToken<Object>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": {\n" + " value:\"foo\"\n" + "}}"); Either<MyClass, List<? extends MyClass>> result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertEquals("foo", result.getLeft().getValue()); message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": [{\n" + " value:\"bar\"\n" + "}]}"); result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); Assert.assertEquals("bar", result.getRight().get(0).getValue()); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_05() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<List<MyClass>, MyClassList>>() {}.getType(), new TypeToken<Object>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": [{\n" + " value:\"foo\"\n" + "}]}"); Either<List<MyClass>, MyClassList> result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertEquals("foo", result.getLeft().get(0).getValue()); message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": {\n" + " items: [{\n" + " value:\"bar\"\n" + "}]}}"); result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); Assert.assertEquals("bar", result.getRight().getItems().get(0).getValue()); }
@Override @SuppressWarnings("unchecked") public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { if (!Message.class.isAssignableFrom(typeToken.getRawType())) return null; return (TypeAdapter<T>) new MessageTypeAdapter(handler, gson); }
@Override public void consume(Message message) { if (message instanceof NotificationMessage) { NotificationMessage notificationMessage = (NotificationMessage) message; handleNotification(notificationMessage); } else if (message instanceof RequestMessage) { RequestMessage requestMessage = (RequestMessage) message; handleRequest(requestMessage); } else if (message instanceof ResponseMessage) { ResponseMessage responseMessage = (ResponseMessage) message; handleResponse(responseMessage); } }
@Override public void consume(Message message) { if (message.getJsonrpc() == null) { message.setJsonrpc(JSONRPC_VERSION); } try { String content = jsonHandler.serialize(message); byte[] contentBytes = content.getBytes(encoding); int contentLength = contentBytes.length; if (output instanceof WebSocketServerOutputStream) { contentLength = content.length(); } String header = getHeader(contentLength); byte[] headerBytes = header.getBytes(StandardCharsets.US_ASCII); synchronized (outputLock) { if (output instanceof WebSocketServerOutputStream) { ((WebSocketServerOutputStream) output).writeString(header + content); } else { output.write(headerBytes); output.write(contentBytes); } output.flush(); } } catch (IOException e) { throw new RuntimeException(e); } }
/** * Returns the deserialized params attribute of a JSON message payload */ @SuppressWarnings("unchecked") public static <T> T getParams(CharSequence jsonPayload) { Message message = handler.parseMessage(jsonPayload); Method getParam = null; try { getParam = message.getClass().getMethod("getParams"); Object params = getParam.invoke(message); return (T)params; } catch (Exception e) { throw new UnsupportedOperationException("Can't deserialize into class"); } }
private void assertIssues(Message message, CharSequence expectedIssues) { try { validator.consume(message); Assert.fail("Expected InvalidMessageException: " + expectedIssues + "."); } catch (InvalidMessageException e) { String expected = expectedIssues.toString(); String actual = LineEndings.toSystemLineEndings(e.getMessage()); // The expectation may be a prefix of the actual exception message if (!actual.startsWith(expected)) Assert.assertEquals(expected, actual); } }
@Override @SuppressWarnings("unchecked") public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { if (!Message.class.isAssignableFrom(typeToken.getRawType())) return null; return (TypeAdapter<T>) new DebugMessageTypeAdapter(handler, gson); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_01() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<String, List<Map<String,String>>>>() {}.getType(), new TypeToken<Either<String, Integer>>() {}.getType())); MessageJsonHandler handler = new MessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + " \"result\": [\n" + " {\"name\":\"foo\"},\n" + " {\"name\":\"bar\"}\n" + "]}"); Either<String, List<Map<String, String>>> result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); for (Map<String, String> e : result.getRight()) { Assert.assertNotNull(e.get("name")); } message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + "\"result\": \"name\"\n" + "}"); result = (Either<String, List<Map<String,String>>>) ((ResponseMessage)message).getResult(); Assert.assertFalse(result.isRight()); Assert.assertEquals("name",result.getLeft()); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_04() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<MyClass, List<? extends MyClass>>>() {}.getType(), new TypeToken<Object>() {}.getType())); MessageJsonHandler handler = new MessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + "\"result\": {\n" + " value:\"foo\"\n" + "}}"); Either<MyClass, List<? extends MyClass>> result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertEquals("foo", result.getLeft().getValue()); message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + "\"result\": [{\n" + " value:\"bar\"\n" + "}]}"); result = (Either<MyClass, List<? extends MyClass>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); Assert.assertEquals("bar", result.getRight().get(0).getValue()); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_05() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<List<MyClass>, MyClassList>>() {}.getType(), new TypeToken<Object>() {}.getType())); MessageJsonHandler handler = new MessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + "\"result\": [{\n" + " value:\"foo\"\n" + "}]}"); Either<List<MyClass>, MyClassList> result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertEquals("foo", result.getLeft().get(0).getValue()); message = handler.parseMessage("{\"jsonrpc\":\"2.0\"," + "\"id\":\"2\",\n" + "\"result\": {\n" + " items: [{\n" + " value:\"bar\"\n" + "}]}}"); result = (Either<List<MyClass>, MyClassList>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); Assert.assertEquals("bar", result.getRight().getItems().get(0).getValue()); }
@Override public void consume(Message message) { if (sentException) { messages.add(message); } else { // throw an exception only for the first message sentException = true; throw new RuntimeException("Exception in consumer"); } }
@Override public Message read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } in.beginObject(); String messageType = null, id = null, seq = null, request_seq = null, method = null, message = null; boolean success = true; Object rawParams = null; Object body = null; while (in.hasNext()) { String name = in.nextName(); switch (name) { case "seq": { seq = in.nextString(); break; } case "request_seq": { // on responses we treat the request_seq as the id request_seq = in.nextString(); break; } case "type": { messageType = in.nextString(); break; } case "success": { success = in.nextBoolean(); break; } case "command": { method = in.nextString(); break; } case "event": { method = in.nextString(); break; } case "message": { message = in.nextString(); break; } case "arguments": { rawParams = parseParams(in, method); break; } case "body": { if ("event".equals(messageType)) { body = parseParams(in, method); } else if ("response".equals(messageType)) { body = parseResult(in, request_seq); } break; } default: in.skipValue(); } } id = request_seq != null ? request_seq : seq; in.endObject(); Object params = parseParams(rawParams, method); return createMessage(messageType, id, method, success, message, params, body); }
@Override public void consume(Message message) { messages.add(message); }
@SuppressWarnings({ "unchecked" }) @Test public void testEither_03() { Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<>(); supportedMethods.put("foo", JsonRpcMethod.request("foo", new TypeToken<Either<Either<MyEnum, Map<String,String>>, List<Either<MyEnum, Map<String,String>>>>>() {}.getType(), new TypeToken<Object>() {}.getType())); DebugMessageJsonHandler handler = new DebugMessageJsonHandler(supportedMethods); handler.setMethodProvider((id) -> "foo"); Message message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + "\"body\": 2\n" + "}"); Either<Either<MyEnum, Map<String,String>>, List<Either<MyEnum, Map<String,String>>>> result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertTrue(result.getLeft().isLeft()); Assert.assertEquals(MyEnum.B, result.getLeft().getLeft()); message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + " \"body\": {\n" + " \"foo\":\"1\",\n" + " \"bar\":\"2\"\n" + "}}"); result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isLeft()); Assert.assertTrue(result.getLeft().isRight()); Assert.assertEquals("1", result.getLeft().getRight().get("foo")); Assert.assertEquals("2", result.getLeft().getRight().get("bar")); message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + " \"body\": [{\n" + " \"foo\":\"1\",\n" + " \"bar\":\"2\"\n" + "}]}"); result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); Assert.assertTrue(result.getRight().get(0).isRight()); Assert.assertEquals("1", result.getRight().get(0).getRight().get("foo")); Assert.assertEquals("2", result.getRight().get(0).getRight().get("bar")); message = handler.parseMessage("{" + "\"seq\":2,\n" + "\"type\":\"response\",\n" + " \"body\": [\n" + " 2\n" + "]}"); result = (Either<Either<MyEnum, Map<String, String>>, List<Either<MyEnum, Map<String, String>>>>) ((ResponseMessage)message).getResult(); Assert.assertTrue(result.isRight()); Assert.assertTrue(result.getRight().get(0).isLeft()); Assert.assertEquals(MyEnum.B, result.getRight().get(0).getLeft()); }
@Override public Message read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } in.beginObject(); String jsonrpc = null, id = null, method = null; Object rawParams = null; Object result = null; ResponseError error = null; while (in.hasNext()) { String name = in.nextName(); switch (name) { case "jsonrpc": { jsonrpc = in.nextString(); break; } case "id": { id = in.nextString(); break; } case "method": { method = in.nextString(); break; } case "params": { rawParams = parseParams(in, method); break; } case "result": { Type type = null; MethodProvider methodProvider = handler.getMethodProvider(); if (methodProvider != null && id != null) { String resolvedMethod = methodProvider.resolveMethod(id); if (resolvedMethod != null) { JsonRpcMethod jsonRpcMethod = handler.getJsonRpcMethod(resolvedMethod); if (jsonRpcMethod != null) type = jsonRpcMethod.getReturnType(); } } if (type == null) result = new JsonParser().parse(in); else result = gson.fromJson(in, type); break; } case "error": { error = gson.fromJson(in, ResponseError.class); break; } default: in.skipValue(); } } in.endObject(); Object params = parseParams(rawParams, method); return createMessage(jsonrpc, id, method, params, result, error); }
public Message parseMessage(CharSequence input) { return gson.fromJson(input.toString(), Message.class); }