forked from eclipse-lsp4j/lsp4j
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide support for Jakarta Websocket eclipse-lsp4j#471
- will require an update of lsp4j.target.target file when orbit bundle will be available, see https://git.eclipse.org/r/c/orbit/orbit-recipes/+/174146 - to avoid API break, created a second bundle with the Jakarta Websocket. it will allow also to support old version too for a moment. the drawback is that it is making the naming a bit more complicated. Signed-off-by: Aurélien Pupier <[email protected]>
- Loading branch information
Showing
15 changed files
with
872 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>org.eclipse.lsp4j.websocket.jakarta</name> | ||
<comment>WebSocket support for LSP4J</comment> | ||
<projects/> | ||
<natures> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature> | ||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature> | ||
</natures> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments/> | ||
</buildCommand> | ||
<buildCommand> | ||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name> | ||
<arguments/> | ||
</buildCommand> | ||
<buildCommand> | ||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name> | ||
<arguments/> | ||
</buildCommand> | ||
</buildSpec> | ||
<linkedResources/> | ||
<filteredResources/> | ||
</projectDescription> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/****************************************************************************** | ||
* Copyright (c) 2019 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 | ||
******************************************************************************/ | ||
|
||
ext.title = 'LSP4J WebSocket Jakarta' | ||
description = 'Jakarta WebSocket support for LSP4J' | ||
|
||
dependencies { | ||
compile project(":org.eclipse.lsp4j.jsonrpc") | ||
compile "jakarta.websocket:jakarta.websocket-api:$versions.websocket_jakarta" | ||
testCompile "junit:junit:$versions.junit" | ||
} | ||
|
||
jar.manifest { | ||
instruction 'Import-Package', '*' | ||
} |
51 changes: 51 additions & 0 deletions
51
...ebsocket.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketEndpoint.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/****************************************************************************** | ||
* Copyright (c) 2021 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.websocket.jakarta; | ||
|
||
import java.util.Collection; | ||
|
||
import jakarta.websocket.Endpoint; | ||
import jakarta.websocket.EndpointConfig; | ||
import jakarta.websocket.Session; | ||
|
||
import org.eclipse.lsp4j.jsonrpc.Launcher; | ||
|
||
/** | ||
* WebSocket endpoint implementation that connects to a JSON-RPC service. | ||
* | ||
* @param <T> remote service interface type | ||
*/ | ||
public abstract class WebSocketEndpoint<T> extends Endpoint { | ||
|
||
@Override | ||
public void onOpen(Session session, EndpointConfig config) { | ||
WebSocketLauncherBuilder<T> builder = new WebSocketLauncherBuilder<>(); | ||
builder.setSession(session); | ||
configure(builder); | ||
Launcher<T> launcher = builder.create(); | ||
connect(builder.getLocalServices(), launcher.getRemoteProxy()); | ||
} | ||
|
||
/** | ||
* Configure the JSON-RPC launcher. Implementations should set at least the | ||
* {@link Launcher.Builder#setLocalService(Object) local service} and the | ||
* {@link Launcher.Builder#setRemoteInterface(Class) remote interface}. | ||
*/ | ||
protected abstract void configure(Launcher.Builder<T> builder); | ||
|
||
/** | ||
* Override this in order to connect the local services to the remote service proxy. | ||
*/ | ||
protected void connect(Collection<Object> localServices, T remoteProxy) { | ||
} | ||
|
||
} |
76 changes: 76 additions & 0 deletions
76
...t.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketLauncherBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/****************************************************************************** | ||
* Copyright (c) 2021 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.websocket.jakarta; | ||
|
||
import java.util.Collection; | ||
|
||
import jakarta.websocket.Session; | ||
|
||
import org.eclipse.lsp4j.jsonrpc.Endpoint; | ||
import org.eclipse.lsp4j.jsonrpc.Launcher; | ||
import org.eclipse.lsp4j.jsonrpc.MessageConsumer; | ||
import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint; | ||
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler; | ||
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints; | ||
|
||
/** | ||
* JSON-RPC launcher builder for use in {@link WebSocketEndpoint}. | ||
* | ||
* @param <T> remote service interface type | ||
*/ | ||
public class WebSocketLauncherBuilder<T> extends Launcher.Builder<T> { | ||
|
||
protected Session session; | ||
|
||
public Collection<Object> getLocalServices() { | ||
return localServices; | ||
} | ||
|
||
public WebSocketLauncherBuilder<T> setSession(Session session) { | ||
this.session = session; | ||
return this; | ||
} | ||
|
||
@Override | ||
public Launcher<T> create() { | ||
if (localServices == null) | ||
throw new IllegalStateException("Local service must be configured."); | ||
if (remoteInterfaces == null) | ||
throw new IllegalStateException("Remote interface must be configured."); | ||
|
||
MessageJsonHandler jsonHandler = createJsonHandler(); | ||
RemoteEndpoint remoteEndpoint = createRemoteEndpoint(jsonHandler); | ||
addMessageHandlers(jsonHandler, remoteEndpoint); | ||
T remoteProxy = createProxy(remoteEndpoint); | ||
return createLauncher(null, remoteProxy, remoteEndpoint, null); | ||
} | ||
|
||
@Override | ||
protected RemoteEndpoint createRemoteEndpoint(MessageJsonHandler jsonHandler) { | ||
MessageConsumer outgoingMessageStream = new WebSocketMessageConsumer(session, jsonHandler); | ||
outgoingMessageStream = wrapMessageConsumer(outgoingMessageStream); | ||
Endpoint localEndpoint = ServiceEndpoints.toEndpoint(localServices); | ||
RemoteEndpoint remoteEndpoint; | ||
if (exceptionHandler == null) | ||
remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint); | ||
else | ||
remoteEndpoint = new RemoteEndpoint(outgoingMessageStream, localEndpoint, exceptionHandler); | ||
jsonHandler.setMethodProvider(remoteEndpoint); | ||
return remoteEndpoint; | ||
} | ||
|
||
protected void addMessageHandlers(MessageJsonHandler jsonHandler, RemoteEndpoint remoteEndpoint) { | ||
MessageConsumer messageConsumer = wrapMessageConsumer(remoteEndpoint); | ||
session.addMessageHandler(new WebSocketMessageHandler(messageConsumer, jsonHandler, remoteEndpoint)); | ||
} | ||
|
||
} |
72 changes: 72 additions & 0 deletions
72
...t.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageConsumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/****************************************************************************** | ||
* Copyright (c) 2021 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.websocket.jakarta; | ||
|
||
import java.io.IOException; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
import jakarta.websocket.Session; | ||
|
||
import org.eclipse.lsp4j.jsonrpc.JsonRpcException; | ||
import org.eclipse.lsp4j.jsonrpc.MessageConsumer; | ||
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler; | ||
import org.eclipse.lsp4j.jsonrpc.messages.Message; | ||
|
||
/** | ||
* Message consumer that sends messages via a WebSocket session. | ||
*/ | ||
public class WebSocketMessageConsumer implements MessageConsumer { | ||
|
||
private static final Logger LOG = Logger.getLogger(WebSocketMessageConsumer.class.getName()); | ||
|
||
private final Session session; | ||
private final MessageJsonHandler jsonHandler; | ||
|
||
public WebSocketMessageConsumer(Session session, MessageJsonHandler jsonHandler) { | ||
this.session = session; | ||
this.jsonHandler = jsonHandler; | ||
} | ||
|
||
public Session getSession() { | ||
return session; | ||
} | ||
|
||
@Override | ||
public void consume(Message message) { | ||
String content = jsonHandler.serialize(message); | ||
try { | ||
sendMessage(content); | ||
} catch (IOException exception) { | ||
throw new JsonRpcException(exception); | ||
} | ||
} | ||
|
||
protected void sendMessage(String message) throws IOException { | ||
if (session.isOpen()) { | ||
int length = message.length(); | ||
if (length <= session.getMaxTextMessageBufferSize()) { | ||
session.getAsyncRemote().sendText(message); | ||
} else { | ||
int currentOffset = 0; | ||
while (currentOffset < length) { | ||
int currentEnd = Math.min(currentOffset + session.getMaxTextMessageBufferSize(), length); | ||
session.getBasicRemote().sendText(message.substring(currentOffset, currentEnd), currentEnd == length); | ||
currentOffset = currentEnd; | ||
} | ||
} | ||
} else { | ||
LOG.log(Level.INFO, "Ignoring message due to closed session: {0}", message); | ||
} | ||
} | ||
|
||
} |
47 changes: 47 additions & 0 deletions
47
...et.jakarta/src/main/java/org/eclipse/lsp4j/websocket/jakarta/WebSocketMessageHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/****************************************************************************** | ||
* Copyright (c) 2021 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.websocket.jakarta; | ||
|
||
import jakarta.websocket.MessageHandler; | ||
|
||
import org.eclipse.lsp4j.jsonrpc.MessageConsumer; | ||
import org.eclipse.lsp4j.jsonrpc.MessageIssueException; | ||
import org.eclipse.lsp4j.jsonrpc.MessageIssueHandler; | ||
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler; | ||
import org.eclipse.lsp4j.jsonrpc.messages.Message; | ||
|
||
/** | ||
* WebSocket message handler that parses JSON messages and forwards them to a {@link MessageConsumer}. | ||
*/ | ||
public class WebSocketMessageHandler implements MessageHandler.Whole<String> { | ||
|
||
private final MessageConsumer callback; | ||
private final MessageJsonHandler jsonHandler; | ||
private final MessageIssueHandler issueHandler; | ||
|
||
public WebSocketMessageHandler(MessageConsumer callback, MessageJsonHandler jsonHandler, MessageIssueHandler issueHandler) { | ||
this.callback = callback; | ||
this.jsonHandler = jsonHandler; | ||
this.issueHandler = issueHandler; | ||
} | ||
|
||
public void onMessage(String content) { | ||
try { | ||
Message message = jsonHandler.parseMessage(content); | ||
callback.consume(message); | ||
} catch (MessageIssueException exception) { | ||
// An issue was found while parsing or validating the message | ||
issueHandler.handle(exception.getRpcMessage(), exception.getIssues()); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.