Skip to content

Commit c5d332b

Browse files
authored
Fixes #536: Restore the pre-Jakarta version of websocket bundle (#539)
Partially reverts "Migrate and Rename Websocket bundle to Jakarta #471 (#487)" This partially reverts commit f44ee42.
1 parent 1c41e8e commit c5d332b

File tree

14 files changed

+843
-0
lines changed

14 files changed

+843
-0
lines changed

gradle/versions.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ ext.versions = [
1919
'gson': '[2.8.6,2.9)',
2020
'gson_orbit': '2.8.6.v20201231-1626',
2121
'websocket_jakarta': '2.0.0',
22+
'websocket': '1.0',
2223
'junit': '4.12'
2324
]
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/******************************************************************************
2+
* Copyright (c) 2019 TypeFox and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
******************************************************************************/
12+
13+
ext.title = 'LSP4J WebSocket'
14+
description = 'WebSocket support for LSP4J'
15+
16+
dependencies {
17+
compile project(":org.eclipse.lsp4j.jsonrpc")
18+
compile "javax.websocket:javax.websocket-api:${versions.websocket}"
19+
testCompile "junit:junit:$versions.junit"
20+
}
21+
22+
jar.manifest {
23+
instruction 'Import-Package', '*'
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/******************************************************************************
2+
* Copyright (c) 2019 TypeFox and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
******************************************************************************/
12+
package org.eclipse.lsp4j.websocket;
13+
14+
import java.util.Collection;
15+
16+
import javax.websocket.Endpoint;
17+
import javax.websocket.EndpointConfig;
18+
import javax.websocket.Session;
19+
20+
import org.eclipse.lsp4j.jsonrpc.Launcher;
21+
22+
/**
23+
* WebSocket endpoint implementation that connects to a JSON-RPC service.
24+
*
25+
* @param <T> remote service interface type
26+
*/
27+
public abstract class WebSocketEndpoint<T> extends Endpoint {
28+
29+
@Override
30+
public void onOpen(Session session, EndpointConfig config) {
31+
WebSocketLauncherBuilder<T> builder = new WebSocketLauncherBuilder<T>();
32+
builder.setSession(session);
33+
configure(builder);
34+
Launcher<T> launcher = builder.create();
35+
connect(builder.getLocalServices(), launcher.getRemoteProxy());
36+
}
37+
38+
/**
39+
* Configure the JSON-RPC launcher. Implementations should set at least the
40+
* {@link Launcher.Builder#setLocalService(Object) local service} and the
41+
* {@link Launcher.Builder#setRemoteInterface(Class) remote interface}.
42+
*/
43+
abstract protected void configure(Launcher.Builder<T> builder);
44+
45+
/**
46+
* Override this in order to connect the local services to the remote service proxy.
47+
*/
48+
protected void connect(Collection<Object> localServices, T remoteProxy) {
49+
}
50+
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/******************************************************************************
2+
* Copyright (c) 2019 TypeFox and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
******************************************************************************/
12+
package org.eclipse.lsp4j.websocket;
13+
14+
import java.util.Collection;
15+
16+
import javax.websocket.Session;
17+
18+
import org.eclipse.lsp4j.jsonrpc.Endpoint;
19+
import org.eclipse.lsp4j.jsonrpc.Launcher;
20+
import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
21+
import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;
22+
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
23+
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
24+
25+
/**
26+
* JSON-RPC launcher builder for use in {@link WebSocketEndpoint}.
27+
*
28+
* @param <T> remote service interface type
29+
*/
30+
public class WebSocketLauncherBuilder<T> extends Launcher.Builder<T> {
31+
32+
protected Session session;
33+
34+
public Collection<Object> getLocalServices() {
35+
return localServices;
36+
}
37+
38+
public WebSocketLauncherBuilder<T> setSession(Session session) {
39+
this.session = session;
40+
return this;
41+
}
42+
43+
@Override
44+
public Launcher<T> create() {
45+
if (localServices == null)
46+
throw new IllegalStateException("Local service must be configured.");
47+
if (remoteInterfaces == null)
48+
throw new IllegalStateException("Remote interface must be configured.");
49+
50+
MessageJsonHandler jsonHandler = createJsonHandler();
51+
RemoteEndpoint remoteEndpoint = createRemoteEndpoint(jsonHandler);
52+
addMessageHandlers(jsonHandler, remoteEndpoint);
53+
T remoteProxy = createProxy(remoteEndpoint);
54+
return createLauncher(null, remoteProxy, remoteEndpoint, null);
55+
}
56+
57+
@Override
58+
protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) {
59+
MessageConsumer outgoingMessageStream = new WebSocketMessageConsumer(session, jsonHandler);
60+
outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream);
61+
Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices);
62+
RemoteEndpoint remoteEndpoint;
63+
if (exceptionHandler == null)
64+
remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint);
65+
else
66+
remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint, exceptionHandler);
67+
jsonHandler.setMethodProvider(remoteEndpoint);
68+
return remoteEndpoint;
69+
}
70+
71+
protected void addMessageHandlers(MessageJsonHandler jsonHandler, RemoteEndpoint remoteEndpoint) {
72+
MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint);
73+
session.addMessageHandler(new WebSocketMessageHandler(messageConsumer, jsonHandler, remoteEndpoint));
74+
}
75+
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/******************************************************************************
2+
* Copyright (c) 2019 TypeFox and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
******************************************************************************/
12+
package org.eclipse.lsp4j.websocket;
13+
14+
import java.io.IOException;
15+
import java.util.logging.Logger;
16+
17+
import javax.websocket.Session;
18+
19+
import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
20+
import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
21+
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
22+
import org.eclipse.lsp4j.jsonrpc.messages.Message;
23+
24+
/**
25+
* Message consumer that sends messages via a WebSocket session.
26+
*/
27+
public class WebSocketMessageConsumer implements MessageConsumer {
28+
29+
private static final Logger LOG = Logger.getLogger(WebSocketMessageConsumer.class.getName());
30+
31+
private final Session session;
32+
private final MessageJsonHandler jsonHandler;
33+
34+
public WebSocketMessageConsumer(Session session, MessageJsonHandler jsonHandler) {
35+
this.session = session;
36+
this.jsonHandler = jsonHandler;
37+
}
38+
39+
public Session getSession() {
40+
return session;
41+
}
42+
43+
@Override
44+
public void consume(Message message) {
45+
String content = jsonHandler.serialize(message);
46+
try {
47+
sendMessage(content);
48+
} catch (IOException exception) {
49+
throw new JsonRpcException(exception);
50+
}
51+
}
52+
53+
protected void sendMessage(String message) throws IOException {
54+
if (session.isOpen()) {
55+
int length = message.length();
56+
if (length <= session.getMaxTextMessageBufferSize()) {
57+
session.getAsyncRemote().sendText(message);
58+
} else {
59+
int currentOffset = 0;
60+
while (currentOffset < length) {
61+
int currentEnd = Math.min(currentOffset + session.getMaxTextMessageBufferSize(), length);
62+
session.getBasicRemote().sendText(message.substring(currentOffset, currentEnd), currentEnd == length);
63+
currentOffset = currentEnd;
64+
}
65+
}
66+
} else {
67+
LOG.info("Ignoring message due to closed session: " + message);
68+
}
69+
}
70+
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/******************************************************************************
2+
* Copyright (c) 2019 TypeFox and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
******************************************************************************/
12+
package org.eclipse.lsp4j.websocket;
13+
14+
import javax.websocket.MessageHandler;
15+
16+
import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
17+
import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
18+
import org.eclipse.lsp4j.jsonrpc.MessageIssueHandler;
19+
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
20+
import org.eclipse.lsp4j.jsonrpc.messages.Message;
21+
22+
/**
23+
* WebSocket message handler that parses JSON messages and forwards them to a {@link MessageConsumer}.
24+
*/
25+
public class WebSocketMessageHandler implements MessageHandler.Whole<String> {
26+
27+
private final MessageConsumer callback;
28+
private final MessageJsonHandler jsonHandler;
29+
private final MessageIssueHandler issueHandler;
30+
31+
public WebSocketMessageHandler(MessageConsumer callback, MessageJsonHandler jsonHandler, MessageIssueHandler issueHandler) {
32+
this.callback = callback;
33+
this.jsonHandler = jsonHandler;
34+
this.issueHandler = issueHandler;
35+
}
36+
37+
public void onMessage(String content) {
38+
try {
39+
Message message = jsonHandler.parseMessage(content);
40+
callback.consume(message);
41+
} catch (MessageIssueException exception) {
42+
// An issue was found while parsing or validating the message
43+
issueHandler.handle(exception.getRpcMessage(), exception.getIssues());
44+
}
45+
}
46+
47+
}

0 commit comments

Comments
 (0)