summaryrefslogtreecommitdiff
path: root/ridljar
diff options
context:
space:
mode:
authorSkyler Grey <skyler.grey@collabora.com>2023-08-18 13:30:35 +0000
committerCaolán McNamara <caolan.mcnamara@collabora.com>2023-09-01 16:55:37 +0200
commit8e246331f6f71320cfcc8defdd04e756a75f71cf (patch)
treec359388bf1fe8051e0a8d6a542afb86c961ebf45 /ridljar
parentcb72f56977faccbda9490bc16ea3cbf7a22c01b0 (diff)
Add a FunctionBasedURPConnection and a websocket URP connector
- FunctionBasedURPConnection is used to enable a client to open a URP connection to a fresh Kit instance in COOL. - This URP connector can be used with that and https://github.com/CollaboraOnline/online/pull/6992 to use a Java Uno Remote Protocol client over websockets - For interoperability with existing Collabora Online websockets a prefix (urp ) is added to each message sent and a similar prefix (urp: ) is expected on each message recieved. This allows sending over the same websocket as other data is being transmitted through. If you are writing a bridge to work with this, you will need to add/strip the prefixes accordingly - This commit uses Java WebSocket (https://github.com/TooTallNate/Java-WebSocket) to send data over websockets. Change-Id: I2bda3d0b988bef7883f9b6829eeb5b7ae8075f27 Signed-off-by: Skyler Grey <skyler.grey@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151171 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'ridljar')
-rw-r--r--ridljar/Jar_libreoffice.mk8
-rw-r--r--ridljar/com/sun/star/comp/helper/Bootstrap.java63
-rw-r--r--ridljar/com/sun/star/lib/connections/websocket/ConnectionDescriptor.java60
-rw-r--r--ridljar/com/sun/star/lib/connections/websocket/WebsocketConnection.java335
-rw-r--r--ridljar/com/sun/star/lib/connections/websocket/websocketConnector.java137
-rw-r--r--ridljar/source/libreoffice/module-info.java1
-rw-r--r--ridljar/util/manifest3
7 files changed, 607 insertions, 0 deletions
diff --git a/ridljar/Jar_libreoffice.mk b/ridljar/Jar_libreoffice.mk
index d34ae3f5ebda..76a56eedc078 100644
--- a/ridljar/Jar_libreoffice.mk
+++ b/ridljar/Jar_libreoffice.mk
@@ -18,11 +18,16 @@ $(eval $(call gb_Jar_use_jars,libreoffice, \
unoloader \
))
+$(eval $(call gb_Jar_use_externals,libreoffice,\
+ java_websocket \
+))
+
$(eval $(call gb_Jar_set_packageroot,libreoffice,com))
$(eval $(call gb_Jar_set_manifest,libreoffice,$(SRCDIR)/ridljar/util/manifest))
$(eval $(call gb_Jar_add_manifest_classpath,libreoffice, \
+ java_websocket.jar \
unoloader.jar \
$(if $(filter MACOSX,$(OS)),../../Frameworks/,../) \
))
@@ -63,6 +68,9 @@ $(eval $(call gb_Jar_add_sourcefiles,libreoffice,\
ridljar/com/sun/star/lib/connections/socket/SocketConnection \
ridljar/com/sun/star/lib/connections/socket/socketAcceptor \
ridljar/com/sun/star/lib/connections/socket/socketConnector \
+ ridljar/com/sun/star/lib/connections/websocket/ConnectionDescriptor \
+ ridljar/com/sun/star/lib/connections/websocket/WebsocketConnection \
+ ridljar/com/sun/star/lib/connections/websocket/websocketConnector \
ridljar/com/sun/star/lib/uno/Proxy \
ridljar/com/sun/star/lib/uno/adapter/ByteArrayToXInputStreamAdapter \
ridljar/com/sun/star/lib/uno/adapter/InputStreamToXInputStreamAdapter \
diff --git a/ridljar/com/sun/star/comp/helper/Bootstrap.java b/ridljar/com/sun/star/comp/helper/Bootstrap.java
index edf21d7d2adf..6b371f50324b 100644
--- a/ridljar/com/sun/star/comp/helper/Bootstrap.java
+++ b/ridljar/com/sun/star/comp/helper/Bootstrap.java
@@ -32,6 +32,7 @@ import com.sun.star.lib.util.NativeLibraryLoader;
import com.sun.star.loader.XImplementationLoader;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
+import com.sun.star.beans.XPropertySet;
import java.io.BufferedReader;
import java.io.File;
@@ -397,6 +398,68 @@ public class Bootstrap {
return xContext;
}
+ /**
+ * Bootstraps the component context from a websocket location.
+ *
+ * @param url
+ * the ws:// or wss:// url of the websocket server
+ *
+ * @throws BootstrapException if things go awry.
+ *
+ * @return a bootstrapped component context.
+ *
+ * @since LibreOffice 24.2
+ */
+ public static final XComponentContext bootstrapWebsocketConnection( String url )
+ throws BootstrapException {
+
+ XComponentContext xContext = null;
+
+ try {
+ // create default local component context
+ XComponentContext xLocalContext =
+ createInitialComponentContext( (Map<String, Object>) null );
+ if ( xLocalContext == null )
+ throw new BootstrapException( "no local component context!" );
+
+ // initial service manager
+ XMultiComponentFactory xLocalServiceManager =
+ xLocalContext.getServiceManager();
+ if ( xLocalServiceManager == null )
+ throw new BootstrapException( "no initial service manager!" );
+
+ // create a URL resolver
+ XUnoUrlResolver xUrlResolver =
+ UnoUrlResolver.create( xLocalContext );
+
+ // connection string
+ String sConnect = "uno:websocket"
+ + ",url=" + url
+ + ";urp;StarOffice.ComponentContext";
+
+ try {
+ // try to connect to office
+ Object xOfficeServiceManager = xUrlResolver.resolve(sConnect);
+
+ xContext = UnoRuntime.queryInterface(XComponentContext.class, xOfficeServiceManager);
+
+ if ( xContext == null )
+ throw new BootstrapException( "no component context!" );
+ } catch ( com.sun.star.connection.NoConnectException ex ) {
+ throw new BootstrapException(ex);
+ }
+ } catch ( BootstrapException e ) {
+ throw e;
+ } catch ( java.lang.RuntimeException e ) {
+ throw e;
+ } catch ( java.lang.Exception e ) {
+ throw new BootstrapException( e );
+ }
+
+ return xContext;
+ }
+
+
private static final Random randomPipeName = new Random();
private static void pipe(
diff --git a/ridljar/com/sun/star/lib/connections/websocket/ConnectionDescriptor.java b/ridljar/com/sun/star/lib/connections/websocket/ConnectionDescriptor.java
new file mode 100644
index 000000000000..439a52551726
--- /dev/null
+++ b/ridljar/com/sun/star/lib/connections/websocket/ConnectionDescriptor.java
@@ -0,0 +1,60 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.lib.connections.websocket;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * Helper class for <code>websocketConnector</code>.
+ */
+final class ConnectionDescriptor {
+ public ConnectionDescriptor(String description)
+ throws com.sun.star.lang.IllegalArgumentException {
+ Iterator<String> descriptionParts = Arrays.stream(description.split(",")).iterator();
+ descriptionParts
+ .next(); // skip over the first part as it's the protocol not a real parameter
+ while (descriptionParts.hasNext())
+ {
+ String parameter = descriptionParts.next();
+ String[] pair = parameter.split("=", 2);
+
+ if (pair.length != 2)
+ {
+ throw new com.sun.star.lang.IllegalArgumentException(
+ String.format("parameter %s lacks '='", parameter));
+ }
+
+ String key = pair[0];
+ String value = pair[1];
+ if (key.equalsIgnoreCase("url")) {
+ url = value;
+ }
+ }
+ }
+
+ public String getURL() {
+ return url;
+ }
+
+ private String url = null;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ridljar/com/sun/star/lib/connections/websocket/WebsocketConnection.java b/ridljar/com/sun/star/lib/connections/websocket/WebsocketConnection.java
new file mode 100644
index 000000000000..7f522df409d1
--- /dev/null
+++ b/ridljar/com/sun/star/lib/connections/websocket/WebsocketConnection.java
@@ -0,0 +1,335 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+package com.sun.star.lib.connections.websocket;
+
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.net.ProtocolException;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.swing.text.html.HTMLDocument.Iterator;
+
+import com.sun.star.connection.XConnection;
+import com.sun.star.connection.XConnectionBroadcaster;
+import com.sun.star.io.XStreamListener;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+
+/**
+ * The WebsocketConnection implements the <code>XConnection</code> interface
+ * and is uses by the <code>WebsocketConnector</code>.
+ *
+ * <p>This class is not part of the provided <code>api</code>.</p>
+ *
+ * @see com.sun.star.lib.connections.socket.socketAcceptor
+ * @see com.sun.star.lib.connections.socket.socketConnector
+ * @see com.sun.star.connection.XConnection
+ */
+public class WebsocketConnection extends WebSocketClient implements XConnection, XConnectionBroadcaster {
+ /**
+ * When set to true, enables various debugging output.
+ */
+ public static final boolean DEBUG = false;
+ static final byte[] outgoingPrefix = { 'u', 'r', 'p', ' ' };
+
+ protected String _description;
+ protected InputStream _inputStream;
+ protected OutputStream _outputStream;
+
+ protected InputStream _outputStreamReader;
+ protected OutputStream _inputStreamWriter;
+
+ protected ArrayList<XStreamListener> _listeners;
+
+ /**
+ * Constructs a new <code>WebsocketConnection</code>.
+ *
+ * @param description the description of the connection.
+ * @param desc the websocket ConnectionDescriptor containing information such as the websocket URL
+ */
+ public WebsocketConnection(String description, ConnectionDescriptor desc) throws IOException, URISyntaxException, InterruptedException {
+ super(new URI(desc.getURL()));
+
+ if (DEBUG) System.err.println("##### " + getClass().getName() + " - instantiated " + description + " " + desc);
+
+ _description = description;
+
+ PipedOutputStream inputStreamWriter = new PipedOutputStream();
+ PipedInputStream inputPipe = new PipedInputStream(inputStreamWriter);
+ PipedOutputStream outputPipe = new PipedOutputStream();
+ PipedInputStream outputStreamReader = new PipedInputStream(outputPipe);
+
+
+ _inputStream = new BufferedInputStream(inputPipe);
+ _inputStreamWriter = inputStreamWriter;
+ _outputStream = new BufferedOutputStream(outputPipe);
+ _outputStreamReader = outputStreamReader;
+
+ _listeners = new ArrayList<XStreamListener>();
+
+ connectBlocking();
+ }
+
+ public void addStreamListener(XStreamListener aListener )
+ throws com.sun.star.uno.RuntimeException {
+ _listeners.add(aListener);
+ }
+
+ public void removeStreamListener(XStreamListener aListener )
+ throws com.sun.star.uno.RuntimeException {
+ _listeners.remove(aListener);
+ }
+
+ private void notifyListeners_open() {
+ for (XStreamListener xStreamListener : _listeners) {
+ xStreamListener.started();
+ }
+ }
+
+ private void notifyListeners_close() {
+ for (XStreamListener xStreamListener : _listeners) {
+ xStreamListener.closed();
+ }
+ }
+
+ private void notifyListeners_error(com.sun.star.uno.Exception exception) {
+ for (XStreamListener xStreamListener : _listeners) {
+ xStreamListener.error(exception);
+ }
+ }
+
+ /**
+ * Read the required number of bytes.
+ *
+ * @param bytes the outparameter, where the bytes have to be placed.
+ * @param nBytesToRead the number of bytes to read.
+ * @return the number of bytes read.
+ *
+ * @see com.sun.star.connection.XConnection#read
+ */
+ public int read(/*OUT*/byte[][] bytes, int nBytesToRead)
+ throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException {
+
+ String errMessage = null;
+
+ int read_bytes = 0;
+ bytes[0] = new byte[nBytesToRead];
+
+ try {
+ _inputStreamWriter.flush();
+
+ int count ;
+
+ do {
+ count = _inputStream.read(bytes[0], read_bytes, nBytesToRead - read_bytes);
+ if(count == -1)
+ errMessage = "EOF reached - " + getDescription();
+
+ read_bytes += count;
+ }
+ while(read_bytes >= 0 && read_bytes < nBytesToRead && count >= 0);
+ } catch(IOException ioException) {
+ if(DEBUG) {
+ System.err.println("##### " + getClass().getName() + ".read - exception occurred:" + ioException);
+ ioException.printStackTrace();
+ }
+
+ errMessage = ioException.toString();
+ }
+
+ if(errMessage != null) {
+ com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(errMessage);
+ notifyListeners_error(unoIOException);
+
+ throw unoIOException;
+ }
+
+ if (DEBUG) System.err.println(String.format("##### %s - read %s bytes of %s requested", getClass().getName(), Integer.toString(read_bytes), Integer.toString(nBytesToRead)));
+
+ return read_bytes;
+ }
+
+ /**
+ * Write bytes.
+ *
+ * @param aData the bytes to write.
+ * @see com.sun.star.connection.XConnection#write
+ */
+ public void write(byte aData[]) throws com.sun.star.io.IOException,
+ com.sun.star.uno.RuntimeException {
+ try {
+ _outputStream.write(aData);
+ } catch(IOException ioException) {
+ com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException);
+ notifyListeners_error(unoIOException);
+
+ throw unoIOException;
+ }
+
+ if (DEBUG) System.err.println(String.format("##### %s - wrote %s bytes", getClass().getName(), Integer.toString(aData.length)));
+ }
+
+ /**
+ * Sends the data over the websocket to whatever is on the other side.
+ *
+ * **NOTE**: unlike with genuine streams, without flushing the data is
+ * never sent
+ *
+ * @see com.sun.star.connection.XConnection#flush
+ */
+ public void flush() throws com.sun.star.io.IOException,
+ com.sun.star.uno.RuntimeException {
+ try {
+ _outputStream.flush();
+
+ Integer available = _outputStreamReader.available();
+
+ byte[] outputBytes = new byte[available + outgoingPrefix.length];
+ System.arraycopy(outgoingPrefix, 0, outputBytes, 0, outgoingPrefix.length);
+
+ _outputStreamReader.read(outputBytes, outgoingPrefix.length, available);
+
+ send(outputBytes);
+ } catch(IOException ioException) {
+ com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException);
+ notifyListeners_error(unoIOException);
+
+ throw unoIOException;
+ }
+
+ if (DEBUG)
+ System.err.println(String.format("##### %s - flushed", getClass().getName()));
+ }
+
+ /**
+ * Closes the connection.
+ *
+ * @see com.sun.star.connection.XConnection#close
+ */
+ public void close() throws com.sun.star.uno.RuntimeException {
+ if (DEBUG) System.err.println("##### " + getClass().getName() + " - socket closed");
+ }
+
+ /**
+ * Gives a description of the connection.
+ *
+ * @return the description.
+ * @see com.sun.star.connection.XConnection#getDescription
+ */
+ public String getDescription() throws com.sun.star.uno.RuntimeException {
+ return _description;
+ }
+
+ @Override
+ public void onOpen(ServerHandshake handshakedata) {
+ notifyListeners_open();
+ }
+
+ @Override
+ public void onClose(int code, String reason, boolean remote) {
+ notifyListeners_close();
+ }
+
+ @Override
+ public void onMessage(String message) {
+ String[] messageParts = message.split(": ", 2);
+ if (messageParts.length != 2)
+ {
+ notifyListeners_error(new com.sun.star.uno.Exception(new ProtocolException(String.format("Recieved URP/WS message (%s) without a type specifier. Messages must be proceeded by 'urp: '", message))));
+ return;
+ }
+
+ String messageType = messageParts[0];
+
+ if (!messageType.equals("urp"))
+ {
+ if (DEBUG) System.err.println(String.format("##### %s - received %s message but that is not URP", getClass().getName(), messageType));
+ return;
+ }
+
+ byte[] messageBytes = messageParts[1].getBytes();
+
+ try {
+ _inputStreamWriter.write(messageBytes);
+ } catch (IOException e) {
+ notifyListeners_error(new com.sun.star.uno.Exception(e));
+ return;
+ }
+
+ if (DEBUG) System.err.println(String.format("##### %s - recieved %s chars", getClass().getName(), Integer.toString(messageBytes.length)));
+ }
+
+ @Override
+ public void onMessage(ByteBuffer message) {
+ byte[] prefixedMessageBytes = message.array();
+
+ String messageType = "";
+ boolean hasType = false;
+ int i;
+ for (i = 0; i < prefixedMessageBytes.length - 1; i++) {
+ if (prefixedMessageBytes[i] == ':' && (prefixedMessageBytes[i+1] == ' ' || prefixedMessageBytes[i+1] == '\n')) {
+ hasType = true;
+ break; // The type ends with ": ", so if we find this sequence we found the end of our type
+ }
+ messageType += (char)prefixedMessageBytes[i];
+ }
+
+ if(!hasType) {
+ notifyListeners_error(new com.sun.star.uno.Exception(new ProtocolException(String.format("Recieved URP/WS message (%s) without a type specifier. Binary messages must be proceeded by 'urp: ' or 'urp:\\n'", message))));
+ return;
+ }
+
+ int messageStartIndex = i + 2;
+
+ if (!messageType.equals("urp")) {
+ if (DEBUG) System.err.println(String.format("##### %s - recieved %s binary message but that is not URP", getClass().getName(), messageType));
+ return;
+ }
+
+ byte[] messageBytes = Arrays.copyOfRange(prefixedMessageBytes, messageStartIndex, prefixedMessageBytes.length);
+
+ try {
+ _inputStreamWriter.write(messageBytes);
+ } catch (IOException e) {
+ notifyListeners_error(new com.sun.star.uno.Exception(e));
+ return;
+ }
+
+ if (DEBUG) System.err.println(String.format("##### %s - recieved %s bytes", getClass().getName(), Integer.toString(prefixedMessageBytes.length)));
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ notifyListeners_error(new com.sun.star.uno.Exception(ex));
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ridljar/com/sun/star/lib/connections/websocket/websocketConnector.java b/ridljar/com/sun/star/lib/connections/websocket/websocketConnector.java
new file mode 100644
index 000000000000..a40bb0093c4d
--- /dev/null
+++ b/ridljar/com/sun/star/lib/connections/websocket/websocketConnector.java
@@ -0,0 +1,137 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.lib.connections.websocket;
+
+import com.sun.star.comp.loader.FactoryHelper;
+import com.sun.star.connection.ConnectionSetupException;
+import com.sun.star.connection.NoConnectException;
+import com.sun.star.connection.XConnection;
+import com.sun.star.connection.XConnector;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.registry.XRegistryKey;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+
+/**
+ * A component that implements the <code>XConnector</code> interface.
+ *
+ * <p>The <code>websocketConnector</code> is a specialized component that uses
+ * websockets for communication. The <code>websocketConnector</code> is generally
+ * used by the <code>com.sun.star.connection.Connector</code> service.</p>
+ *
+ * @see com.sun.star.connection.XAcceptor
+ * @see com.sun.star.connection.XConnection
+ * @see com.sun.star.connection.XConnector
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+public final class websocketConnector implements XConnector {
+ /**
+ * The name of the service.
+ *
+ * <p>The <code>JavaLoader</code> accesses this through reflection.</p>
+ *
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static final String __serviceName
+ = "com.sun.star.connection.websocketConnector";
+
+ /**
+ * Returns a factory for creating the service.
+ *
+ * <p>This method is called by the <code>JavaLoader</code>.</p>
+ *
+ * @param implName the name of the implementation for which a service is
+ * requested.
+ * @param multiFactory the service manager to be used (if needed).
+ * @param regKey the registry key.
+ * @return an <code>XSingleServiceFactory</code> for creating the component.
+ *
+ * @see com.sun.star.comp.loader.JavaLoader
+ */
+ public static XSingleServiceFactory __getServiceFactory(
+ String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey)
+ {
+ return implName.equals(websocketConnector.class.getName())
+ ? FactoryHelper.getServiceFactory(websocketConnector.class,
+ __serviceName, multiFactory,
+ regKey)
+ : null;
+ }
+
+ /**
+ * Connects via the described websocket to a waiting server.
+ *
+ * <p>The connection description has the following format:
+ * <code><var>type</var></code><!--
+ * -->*(<code><var>key</var>=<var>value</var></code>),
+ * where <code><var>type</var></code> should be <code>websocket</code>
+ * (ignoring case). Supported keys (ignoring case) currently are</p>
+ * <dl>
+ * <dt><code>url</code>
+ * <dd>The URL the websocket server is listening on, starting with
+ * either ws:// or wss://
+ * </dl>
+ *
+ * @param connectionDescription the description of the connection.
+ * @return an <code>XConnection</code> to the server.
+ *
+ * @see com.sun.star.connection.XAcceptor
+ * @see com.sun.star.connection.XConnection
+ */
+ public synchronized XConnection connect(String connectionDescription)
+ throws NoConnectException, ConnectionSetupException
+ {
+ if (connected)
+ throw new ConnectionSetupException("Already connected to the socket");
+
+ ConnectionDescriptor desc;
+ try {
+ desc = new ConnectionDescriptor(connectionDescription);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ throw new ConnectionSetupException(e);
+ }
+
+ WebsocketConnection websocket = null;
+ try {
+ websocket = new WebsocketConnection(connectionDescription, desc);
+ connected = websocket.isOpen();
+ } catch (IOException e) {
+ throw new ConnectionSetupException(e);
+ } catch (URISyntaxException e) {
+ throw new ConnectionSetupException(e);
+ } catch (InterruptedException e) {
+ throw new ConnectionSetupException(e);
+ }
+
+ if (websocket == null || !connected)
+ throw new ConnectionSetupException("Could not connect to the server. Is it up?");
+
+ return websocket;
+ }
+
+ private boolean connected = false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ridljar/source/libreoffice/module-info.java b/ridljar/source/libreoffice/module-info.java
index 8d24c7ccb13c..f913597600db 100644
--- a/ridljar/source/libreoffice/module-info.java
+++ b/ridljar/source/libreoffice/module-info.java
@@ -64,6 +64,7 @@ module org.libreoffice.uno
exports com.sun.star.ldap;
exports com.sun.star.lib.connections.pipe;
exports com.sun.star.lib.connections.socket;
+ exports com.sun.star.lib.connections.websocket;
exports com.sun.star.lib.uno;
exports com.sun.star.lib.uno.adapter;
exports com.sun.star.lib.uno.bridges.java_remote;
diff --git a/ridljar/util/manifest b/ridljar/util/manifest
index bb1209f90a22..44eb59ff784b 100644
--- a/ridljar/util/manifest
+++ b/ridljar/util/manifest
@@ -24,6 +24,9 @@ Sealed: true
Name: com/sun/star/lib/connections/socket/
Sealed: true
+Name: com/sun/star/lib/connections/websocket/
+Sealed: true
+
Name: com/sun/star/lib/uno/
Sealed: true