diff --git a/org.eclipse.lsp4j.jsonrpc.debug/src/main/java/org/eclipse/lsp4j/jsonrpc/debug/DebugLauncher.java b/org.eclipse.lsp4j.jsonrpc.debug/src/main/java/org/eclipse/lsp4j/jsonrpc/debug/DebugLauncher.java index 6c60a43f7..49a3593be 100644 --- a/org.eclipse.lsp4j.jsonrpc.debug/src/main/java/org/eclipse/lsp4j/jsonrpc/debug/DebugLauncher.java +++ b/org.eclipse.lsp4j.jsonrpc.debug/src/main/java/org/eclipse/lsp4j/jsonrpc/debug/DebugLauncher.java @@ -210,7 +210,7 @@ protected MessageJsonHandler createJsonHandler() { @Override protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) { MessageConsumer outgoingMessageStream = new StreamMessageConsumer(output, jsonHandler); - outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream); + outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream, jsonHandler); Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices); RemoteEndpoint remoteEndpoint; if (exceptionHandler == null) diff --git a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Launcher.java b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Launcher.java index b543a739e..e16b3885d 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Launcher.java +++ b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Launcher.java @@ -235,7 +235,7 @@ public static class Builder { protected boolean validateMessages; protected Consumer configureGson; protected ClassLoader classLoader; - protected MessageTracer messageTracer; + protected PrintWriter messageTracer; public Builder setLocalService(Object localService) { this.localServices = Collections.singletonList(localService); @@ -294,7 +294,7 @@ public Builder validateMessages(boolean validate) { public Builder traceMessages(PrintWriter tracer) { if (tracer != null) { - this.messageTracer = new MessageTracer(tracer); + this.messageTracer = tracer; } return this; } @@ -322,7 +322,7 @@ public Launcher create() { // Create the message processor StreamMessageProducer reader = new StreamMessageProducer(input, jsonHandler, remoteEndpoint); - MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint); + MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint, jsonHandler); ConcurrentMessageProcessor msgProcessor = createMessageProcessor(reader, messageConsumer, remoteProxy); ExecutorService execService = executorService != null ? executorService : Executors.newCachedThreadPool(); return createLauncher(execService, remoteProxy, remoteEndpoint, msgProcessor); @@ -344,7 +344,7 @@ protected MessageJsonHandler createJsonHandler() { */ protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) { MessageConsumer outgoingMessageStream = new StreamMessageConsumer(output, jsonHandler); - outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream); + outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream, jsonHandler); Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices); RemoteEndpoint remoteEndpoint; if (exceptionHandler == null) @@ -380,10 +380,10 @@ protected Launcher createLauncher(ExecutorService execService, T remoteProxy, return new StandardLauncher(execService, remoteProxy, remoteEndpoint, msgProcessor); } - protected MessageConsumer wrapMessageConsumer(MessageConsumer consumer) { + protected MessageConsumer wrapMessageConsumer(MessageConsumer consumer, MessageJsonHandler jsonHandler) { MessageConsumer result = consumer; if (messageTracer != null) { - result = messageTracer.apply(consumer); + result = new MessageTracer(messageTracer, jsonHandler).apply(consumer); } if (validateMessages) { result = new ReflectiveMessageValidator(result); diff --git a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/MessageTracer.java b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/MessageTracer.java index 8398f6f19..2b47060e1 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/MessageTracer.java +++ b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/MessageTracer.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Objects; import java.util.function.Function; +import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler; /** * Wraps a {@link MessageConsumer} with one that logs in a way that the LSP Inspector can parse. * @@ -26,16 +27,18 @@ */ public class MessageTracer implements Function { private final PrintWriter printWriter; + private final MessageJsonHandler jsonHandler; private final Map sentRequests = new HashMap<>(); private final Map receivedRequests = new HashMap<>(); - MessageTracer(PrintWriter printWriter) { + MessageTracer(PrintWriter printWriter, MessageJsonHandler jsonHandler) { this.printWriter = Objects.requireNonNull(printWriter); + this.jsonHandler = Objects.requireNonNull(jsonHandler); } @Override public MessageConsumer apply(MessageConsumer messageConsumer) { return new TracingMessageConsumer( - messageConsumer, sentRequests, receivedRequests, printWriter, Clock.systemDefaultZone()); + messageConsumer, sentRequests, receivedRequests, printWriter, jsonHandler, Clock.systemDefaultZone()); } } diff --git a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/TracingMessageConsumer.java b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/TracingMessageConsumer.java index 5730e11b1..9aaac9475 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/TracingMessageConsumer.java +++ b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/TracingMessageConsumer.java @@ -40,6 +40,7 @@ public class TracingMessageConsumer implements MessageConsumer { private final Map sentRequests; private final Map receivedRequests; private final PrintWriter printWriter; + private final MessageJsonHandler jsonHandler; private final Clock clock; private final DateTimeFormatter dateTimeFormatter; @@ -55,8 +56,9 @@ public TracingMessageConsumer( Map sentRequests, Map receivedRequests, PrintWriter printWriter, + MessageJsonHandler jsonHandler, Clock clock) { - this(messageConsumer, sentRequests, receivedRequests, printWriter, clock, null); + this(messageConsumer, sentRequests, receivedRequests, printWriter, jsonHandler, clock, null); } /** @@ -72,12 +74,14 @@ public TracingMessageConsumer( Map sentRequests, Map receivedRequests, PrintWriter printWriter, + MessageJsonHandler jsonHandler, Clock clock, Locale locale) { this.messageConsumer = Objects.requireNonNull(messageConsumer); this.sentRequests = Objects.requireNonNull(sentRequests); this.receivedRequests = Objects.requireNonNull(receivedRequests); this.printWriter = Objects.requireNonNull(printWriter); + this.jsonHandler = jsonHandler; this.clock = Objects.requireNonNull(clock); if (locale == null) { this.dateTimeFormatter = DateTimeFormatter.ofPattern("KK:mm:ss a").withZone(clock.getZone()); @@ -122,7 +126,7 @@ private String consumeMessageSending(Message message, Instant now, String date) RequestMetadata requestMetadata = new RequestMetadata(method, now); sentRequests.put(id, requestMetadata); Object params = requestMessage.getParams(); - String paramsJson = MessageJsonHandler.toString(params); + String paramsJson = jsonHandler.toString(params); String format = "[Trace - %s] Sending request '%s - (%s)'\nParams: %s\n\n\n"; return String.format(format, date, method, id, paramsJson); } else if (message instanceof ResponseMessage) { @@ -136,7 +140,7 @@ private String consumeMessageSending(Message message, Instant now, String date) String method = requestMetadata.method; long latencyMillis = now.toEpochMilli() - requestMetadata.start.toEpochMilli(); Object result = responseMessage.getResult(); - String resultJson = MessageJsonHandler.toString(result); + String resultJson = jsonHandler.toString(result); String format = "[Trace - %s] Sending response '%s - (%s)'. Processing request took %sms\nResult: %s\n\n\n"; return String.format(format, date, method, id, latencyMillis, resultJson); @@ -144,7 +148,7 @@ private String consumeMessageSending(Message message, Instant now, String date) NotificationMessage notificationMessage = (NotificationMessage) message; String method = notificationMessage.getMethod(); Object params = notificationMessage.getParams(); - String paramsJson = MessageJsonHandler.toString(params); + String paramsJson = jsonHandler.toString(params); String format = "[Trace - %s] Sending notification '%s'\nParams: %s\n\n\n"; return String.format(format, date, method, paramsJson); } else { @@ -161,7 +165,7 @@ private String consumeMessageReceiving(Message message, Instant now, String date RequestMetadata requestMetadata = new RequestMetadata(method, now); receivedRequests.put(id, requestMetadata); Object params = requestMessage.getParams(); - String paramsJson = MessageJsonHandler.toString(params); + String paramsJson = jsonHandler.toString(params); String format = "[Trace - %s] Received request '%s - (%s)'\nParams: %s\n\n\n"; return String.format(format, date, method, id, paramsJson); } else if (message instanceof ResponseMessage) { @@ -169,22 +173,22 @@ private String consumeMessageReceiving(Message message, Instant now, String date String id = responseMessage.getId(); RequestMetadata requestMetadata = sentRequests.remove(id); if (requestMetadata == null) { - LOG.log(WARNING, String.format("Unmatched response message: %s", message)); + LOG.log(WARNING, String.format("Unmatched response message: %s", jsonHandler.toString(message))); return null; } String method = requestMetadata.method; long latencyMillis = now.toEpochMilli() - requestMetadata.start.toEpochMilli(); Object result = responseMessage.getResult(); - String resultJson = MessageJsonHandler.toString(result); + String resultJson = jsonHandler.toString(result); Object error = responseMessage.getError(); - String errorJson = MessageJsonHandler.toString(error); + String errorJson = jsonHandler.toString(error); String format = "[Trace - %s] Received response '%s - (%s)' in %sms\nResult: %s\nError: %s\n\n\n"; return String.format(format, date, method, id, latencyMillis, resultJson, errorJson); } else if (message instanceof NotificationMessage) { NotificationMessage notificationMessage = (NotificationMessage) message; String method = notificationMessage.getMethod(); Object params = notificationMessage.getParams(); - String paramsJson = MessageJsonHandler.toString(params); + String paramsJson = jsonHandler.toString(params); String format = "[Trace - %s] Received notification '%s'\nParams: %s\n\n\n"; return String.format(format, date, method, paramsJson); } else { diff --git a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java index f7584c810..184282b8c 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java +++ b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java @@ -11,6 +11,8 @@ ******************************************************************************/ package org.eclipse.lsp4j.jsonrpc.json; +import com.google.gson.JsonNull; +import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.io.Reader; import java.io.StringReader; @@ -48,7 +50,7 @@ public class MessageJsonHandler { public static final JsonRpcMethod CANCEL_METHOD = JsonRpcMethod.notification("$/cancelRequest", CancelParams.class); private final Gson gson; - + private final Map supportedMethods; private MethodProvider methodProvider; @@ -144,21 +146,27 @@ public String serialize(Message message) { public void serialize(Message message, Writer output) throws JsonIOException { gson.toJson(message, Message.class, output); } - - - private static MessageJsonHandler toStringInstance; - + /** - * Perform JSON serialization of the given object using the default configuration of JSON-RPC messages + * Perform JSON serialization of the given object using the configuration of JSON-RPC messages * enhanced with the pretty printing option. */ - public static String toString(Object object) { - if (toStringInstance == null) { - toStringInstance = new MessageJsonHandler(Collections.emptyMap(), gsonBuilder -> { - gsonBuilder.setPrettyPrinting(); - }); + public String toString(Object object) { + StringWriter writer = new StringWriter(); + JsonWriter jsonWriter = null; + try { + jsonWriter = gson.newJsonWriter(writer); + // Equivalent to set pretty printing on the gson builder + jsonWriter.setIndent(" "); + } catch (IOException e) { + throw new JsonIOException(e); + } + if (object != null) { + gson.toJson(object, object.getClass(), jsonWriter); + } else { + gson.toJson(JsonNull.INSTANCE, jsonWriter); } - return toStringInstance.gson.toJson(object); + return writer.toString(); } - + } diff --git a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/CancelParams.java b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/CancelParams.java index 2c6a35ff6..ee48f69ee 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/CancelParams.java +++ b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/CancelParams.java @@ -52,11 +52,6 @@ public void setId(@NonNull int id) { public void setRawId(@NonNull Either id) { this.id = id; } - - @Override - public String toString() { - return MessageJsonHandler.toString(this); - } @Override public boolean equals(final Object obj) { diff --git a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/Message.java b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/Message.java index 5d4be746c..afc67d830 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/Message.java +++ b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/Message.java @@ -33,11 +33,6 @@ public void setJsonrpc(@NonNull String jsonrpc) { this.jsonrpc = jsonrpc; } - @Override - public String toString() { - return MessageJsonHandler.toString(this); - } - @Override public boolean equals(final Object obj) { if (this == obj) diff --git a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java index 64b8888d5..dced66131 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java +++ b/org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/messages/ResponseError.java @@ -81,11 +81,6 @@ public ResponseError(int code, String message, Object data) { this.data = data; } - @Override - public String toString() { - return MessageJsonHandler.toString(this); - } - @Override public boolean equals(final Object obj) { if (this == obj) diff --git a/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/IntegrationTest.java b/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/IntegrationTest.java index d7ba4db7d..c81d6cfcf 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/IntegrationTest.java +++ b/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/IntegrationTest.java @@ -18,6 +18,10 @@ import java.io.ByteArrayOutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -83,6 +87,16 @@ public Either getEither() { public void setEither(Either either) { this.either = either; } + + private Path customAdapter; + + public Path getCustomAdapter() { + return customAdapter; + } + + public void setCustomAdapter(Path customAdapter) { + this.customAdapter = customAdapter; + } } public static interface MyServer { @@ -727,6 +741,62 @@ public void testValidationIssue2() throws Exception { out.toString()); } + @Test + public void testMessageTracingWithCustomGsonAdapter() throws Exception { + // create client side + PipedInputStream in = new PipedInputStream(); + PipedOutputStream out = new PipedOutputStream(); + PipedInputStream in2 = new PipedInputStream(); + PipedOutputStream out2 = new PipedOutputStream(); + + in.connect(out2); + out.connect(in2); + + StringWriter clientTraceOut = new StringWriter(); + StringWriter serverTraceOut = new StringWriter(); + + MyClient client = new MyClientImpl(); + Launcher clientSideLauncher = new Launcher.Builder() + .setLocalService(client) + .setRemoteInterface(MyServer.class) + .setInput(in) + .setOutput(out) + .configureGson(gsonBuilder -> gsonBuilder.registerTypeHierarchyAdapter(Path.class, new PathTypeAdapter())) + .traceMessages(new PrintWriter(clientTraceOut)) + .create(); + + // create server side + MyServer server = new MyServerImpl(); + Launcher serverSideLauncher = new Launcher.Builder() + .setLocalService(server) + .setRemoteInterface(MyClient.class) + .setInput(in2) + .setOutput(out2) + .configureGson(gsonBuilder -> gsonBuilder.registerTypeHierarchyAdapter(Path.class, new PathTypeAdapter())) + .traceMessages(new PrintWriter(serverTraceOut)) + .create(); + + clientSideLauncher.startListening(); + serverSideLauncher.startListening(); + + var paramWithPath = new MyParam("FOO"); + paramWithPath.setCustomAdapter(Paths.get("").toAbsolutePath()); + CompletableFuture fooFuture = clientSideLauncher.getRemoteProxy().askServer(paramWithPath); + CompletableFuture barFuture = serverSideLauncher.getRemoteProxy().askClient(new MyParam("BAR")); + + Assert.assertEquals(Paths.get("").toAbsolutePath(), fooFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).getCustomAdapter()); + Assert.assertEquals("BAR", barFuture.get(TIMEOUT, TimeUnit.MILLISECONDS).value); + + Assert.assertTrue(clientTraceOut.toString().contains("Sending request 'askServer - (1)'\n" + + "Params: {\n" + + " \"value\": \"FOO\",\n" + + " \"customAdapter\": \"")); + Assert.assertTrue(serverTraceOut.toString().contains("Received request 'askServer - (1)'\n" + + "Params: {\n" + + " \"value\": \"FOO\",\n" + + " \"customAdapter\": \"")); + } + protected String getHeader(int contentLength) { StringBuilder headerBuilder = new StringBuilder(); headerBuilder.append(CONTENT_LENGTH_HEADER).append(": ").append(contentLength).append(CRLF); diff --git a/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/PathTypeAdapter.java b/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/PathTypeAdapter.java new file mode 100644 index 000000000..8218a3e15 --- /dev/null +++ b/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/PathTypeAdapter.java @@ -0,0 +1,41 @@ +/****************************************************************************** + * Copyright (c) 2016 TypeFox and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + ******************************************************************************/ +package org.eclipse.lsp4j.jsonrpc.test; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.nio.file.Path; + +public class PathTypeAdapter extends TypeAdapter { + + @Override + public void write(JsonWriter out, Path value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + out.value(value.toString()); + } + } + + @Override + public Path read(JsonReader in) throws IOException { + var peek = in.peek(); + if (peek == JsonToken.NULL) { + in.nextNull(); + return null; + } + return Path.of(in.nextString()); + } +} \ No newline at end of file diff --git a/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/TracingMessageConsumerTest.java b/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/TracingMessageConsumerTest.java index a51453266..5001e04cc 100644 --- a/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/TracingMessageConsumerTest.java +++ b/org.eclipse.lsp4j.jsonrpc/src/test/java/org/eclipse/lsp4j/jsonrpc/test/TracingMessageConsumerTest.java @@ -11,6 +11,8 @@ ******************************************************************************/ package org.eclipse.lsp4j.jsonrpc.test; +import java.nio.file.Path; +import java.nio.file.Paths; import org.eclipse.lsp4j.jsonrpc.*; import org.eclipse.lsp4j.jsonrpc.TracingMessageConsumer.RequestMetadata; import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler; @@ -34,9 +36,10 @@ public class TracingMessageConsumerTest { private static final RemoteEndpoint TEST_REMOTE_ENDPOINT = new EmptyRemoteEndpoint(); - private static final StreamMessageConsumer TEST_STREAM_MESSAGE_CONSUMER = - new StreamMessageConsumer( - new ByteArrayOutputStream(), new MessageJsonHandler(emptyMap())); + private static final MessageJsonHandler jsonHandler = new MessageJsonHandler(emptyMap(), gsonBuilder -> { + gsonBuilder.registerTypeHierarchyAdapter(Path.class, new PathTypeAdapter()); + }); + private static final StreamMessageConsumer TEST_STREAM_MESSAGE_CONSUMER = new StreamMessageConsumer(new ByteArrayOutputStream(), jsonHandler); private static final Clock TEST_CLOCK_1 = Clock.fixed(Instant.parse("2019-06-26T22:07:30.00Z"), ZoneId.of("America/New_York")); private static final Clock TEST_CLOCK_2 = @@ -49,7 +52,7 @@ public void testReceivedRequest() { TracingMessageConsumer consumer = new TracingMessageConsumer( - TEST_REMOTE_ENDPOINT, new HashMap<>(), new HashMap<>(), printWriter, TEST_CLOCK_1, Locale.US); + TEST_REMOTE_ENDPOINT, new HashMap<>(), new HashMap<>(), printWriter, jsonHandler, TEST_CLOCK_1, Locale.US); RequestMessage message = new RequestMessage(); message.setId("1"); @@ -78,7 +81,7 @@ public void testReceivedResultResponse() { TracingMessageConsumer consumer = new TracingMessageConsumer( - TEST_REMOTE_ENDPOINT, sentRequests, new HashMap<>(), printWriter, TEST_CLOCK_2, Locale.US); + TEST_REMOTE_ENDPOINT, sentRequests, new HashMap<>(), printWriter, jsonHandler, TEST_CLOCK_2, Locale.US); ResponseMessage message = new ResponseMessage(); message.setId("1"); @@ -107,7 +110,7 @@ public void testReceivedErrorResponse() { TracingMessageConsumer consumer = new TracingMessageConsumer( - TEST_REMOTE_ENDPOINT, sentRequests, new HashMap<>(), printWriter, TEST_CLOCK_2, Locale.US); + TEST_REMOTE_ENDPOINT, sentRequests, new HashMap<>(), printWriter, jsonHandler, TEST_CLOCK_2, Locale.US); ResponseMessage message = new ResponseMessage(); message.setId("1"); @@ -129,6 +132,39 @@ public void testReceivedErrorResponse() { assertEquals(expectedTrace, actualTrace); } + @Test + public void testReceivedErrorResponseWithCustomDataAdapter() { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + + Map sentRequests = new HashMap<>(); + sentRequests.put("1", new RequestMetadata("foo", TEST_CLOCK_1.instant())); + + TracingMessageConsumer consumer = + new TracingMessageConsumer( + TEST_REMOTE_ENDPOINT, sentRequests, new HashMap<>(), printWriter, jsonHandler, TEST_CLOCK_2, Locale.US); + + ResponseMessage message = new ResponseMessage(); + message.setId("1"); + message.setError(new ResponseError(-32600, "bar", Paths.get("foo/Bar.java"))); + + consumer.consume(message); + + String actualTrace = stringWriter.toString(); + String expectedTrace = "" + + "[Trace - 06:07:30 PM] Received response 'foo - (1)' in 100ms\n" + + "Result: null\n" + + "Error: {\n" + + " \"code\": -32600,\n" + + " \"message\": \"bar\",\n" + + " \"data\": \"foo/Bar.java\"\n" + + "}\n" + + "\n" + + "\n"; + + assertEquals(expectedTrace, actualTrace); + } + @Test public void testReceivedNotification() { StringWriter stringWriter = new StringWriter(); @@ -136,7 +172,7 @@ public void testReceivedNotification() { TracingMessageConsumer consumer = new TracingMessageConsumer( - TEST_REMOTE_ENDPOINT, new HashMap<>(), new HashMap<>(), printWriter, TEST_CLOCK_1, Locale.US); + TEST_REMOTE_ENDPOINT, new HashMap<>(), new HashMap<>(), printWriter, jsonHandler, TEST_CLOCK_1, Locale.US); NotificationMessage message = new NotificationMessage(); message.setMethod("foo"); @@ -161,7 +197,7 @@ public void testSendingRequest() { TracingMessageConsumer consumer = new TracingMessageConsumer( - TEST_STREAM_MESSAGE_CONSUMER, new HashMap<>(), new HashMap<>(), printWriter, TEST_CLOCK_1, Locale.US); + TEST_STREAM_MESSAGE_CONSUMER, new HashMap<>(), new HashMap<>(), printWriter, jsonHandler, TEST_CLOCK_1, Locale.US); RequestMessage message = new RequestMessage(); message.setId("1"); @@ -190,7 +226,7 @@ public void testSendingResponse() { TracingMessageConsumer consumer = new TracingMessageConsumer( - TEST_STREAM_MESSAGE_CONSUMER, new HashMap<>(), receivedRequests, printWriter, TEST_CLOCK_2, Locale.US); + TEST_STREAM_MESSAGE_CONSUMER, new HashMap<>(), receivedRequests, printWriter, jsonHandler, TEST_CLOCK_2, Locale.US); ResponseMessage message = new ResponseMessage(); message.setId("1"); @@ -215,7 +251,7 @@ public void testSendingNotification() { TracingMessageConsumer consumer = new TracingMessageConsumer( - TEST_STREAM_MESSAGE_CONSUMER, emptyMap(), emptyMap(), printWriter, TEST_CLOCK_1, Locale.US); + TEST_STREAM_MESSAGE_CONSUMER, emptyMap(), emptyMap(), printWriter, jsonHandler, TEST_CLOCK_1, Locale.US); NotificationMessage message = new NotificationMessage(); message.setMethod("foo"); @@ -232,6 +268,31 @@ public void testSendingNotification() { assertEquals(expectedTrace, actualTrace); } + + @Test + public void testSendingNotificationWithCustomAdapter() { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + + TracingMessageConsumer consumer = + new TracingMessageConsumer( + TEST_STREAM_MESSAGE_CONSUMER, emptyMap(), emptyMap(), printWriter, jsonHandler, TEST_CLOCK_1, Locale.US); + + NotificationMessage message = new NotificationMessage(); + message.setMethod("foo"); + message.setParams(Paths.get("foo/Bar.java")); + + consumer.consume(message); + + String actualTrace = stringWriter.toString(); + String expectedTrace = "" + + "[Trace - 06:07:30 PM] Sending notification 'foo'\n" + + "Params: \"foo/Bar.java\"\n" + + "\n" + + "\n"; + + assertEquals(expectedTrace, actualTrace); + } } class EmptyRemoteEndpoint extends RemoteEndpoint { diff --git a/org.eclipse.lsp4j.websocket.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java b/org.eclipse.lsp4j.websocket.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java index 7fdf1e3ae..19ed8f6a5 100644 --- a/org.eclipse.lsp4j.websocket.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java +++ b/org.eclipse.lsp4j.websocket.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java @@ -57,7 +57,7 @@ public Launcher create() { @Override protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) { MessageConsumer outgoingMessageStream = new WebSocketMessageConsumer(session, jsonHandler); - outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream); + outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream, jsonHandler); Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices); RemoteEndpoint remoteEndpoint; if (exceptionHandler == null) @@ -69,7 +69,7 @@ protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) { } protected void addMessageHandlers(MessageJsonHandler jsonHandler, RemoteEndpoint remoteEndpoint) { - MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint); + MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint, jsonHandler); session.addMessageHandler(new WebSocketMessageHandler(messageConsumer, jsonHandler, remoteEndpoint)); } diff --git a/org.eclipse.lsp4j.websocket/src/main/java/org/eclipse/lsp4j/websocket/WebSocketLauncherBuilder.java b/org.eclipse.lsp4j.websocket/src/main/java/org/eclipse/lsp4j/websocket/WebSocketLauncherBuilder.java index 5a5288634..c43de466a 100644 --- a/org.eclipse.lsp4j.websocket/src/main/java/org/eclipse/lsp4j/websocket/WebSocketLauncherBuilder.java +++ b/org.eclipse.lsp4j.websocket/src/main/java/org/eclipse/lsp4j/websocket/WebSocketLauncherBuilder.java @@ -57,7 +57,7 @@ public Launcher create() { @Override protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) { MessageConsumer outgoingMessageStream = new WebSocketMessageConsumer(session, jsonHandler); - outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream); + outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream, jsonHandler); Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices); RemoteEndpoint remoteEndpoint; if (exceptionHandler == null) @@ -69,7 +69,7 @@ protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) { } protected void addMessageHandlers(MessageJsonHandler jsonHandler, RemoteEndpoint remoteEndpoint) { - MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint); + MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint, jsonHandler); session.addMessageHandler(new WebSocketMessageHandler(messageConsumer, jsonHandler, remoteEndpoint)); } diff --git a/org.eclipse.lsp4j/src/test/java/org/eclipse/lsp4j/test/services/JsonParseTest.xtend b/org.eclipse.lsp4j/src/test/java/org/eclipse/lsp4j/test/services/JsonParseTest.xtend index 3c8d8e532..f506710c8 100644 --- a/org.eclipse.lsp4j/src/test/java/org/eclipse/lsp4j/test/services/JsonParseTest.xtend +++ b/org.eclipse.lsp4j/src/test/java/org/eclipse/lsp4j/test/services/JsonParseTest.xtend @@ -164,7 +164,7 @@ class JsonParseTest { private def void assertParse(CharSequence json, Message expected) { val actual = jsonHandler.parseMessage(json) - assertEquals(expected.toString, actual.toString) + assertEquals(jsonHandler.toString(expected), jsonHandler.toString(actual)) assertEquals(expected, actual) }