All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.iti.wakamiti.lsp.TcpSocketLanguageServer Maven / Gradle / Ivy

/*
 * 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 https://mozilla.org/MPL/2.0/.
 */

package es.iti.wakamiti.lsp;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executors;

import es.iti.wakamiti.core.Wakamiti;
import es.iti.wakamiti.api.WakamitiException;
import org.eclipse.lsp4j.launch.LSPLauncher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import es.iti.wakamiti.api.*;


public class TcpSocketLanguageServer  {

    private static final Logger LOGGER = LoggerFactory.getLogger(TcpSocketLanguageServer.class);

    private final InetSocketAddress endpoint;
    private final Thread internalRunner;
    private final int baseIndex;

    private ServerSocket serverSocket;

    public TcpSocketLanguageServer(InetSocketAddress address, int baseIndex) {
        this.endpoint = address;
        this.internalRunner = new Thread(this::run);
        this.baseIndex = baseIndex;
    }


    public void start() throws IOException {
        serverSocket = new ServerSocket();
        serverSocket.bind(endpoint);
        internalRunner.start();
        LOGGER.info("Language Server listening at {}:{}", getAddress(), getPort());
    }


   private void run() {
	    LOGGER.info("Contributors available: {}", Wakamiti.contributors().allContributors());
        var threadPool = Executors.newCachedThreadPool();
        while (!serverSocket.isClosed()) {
            Socket socket;
            try {
                socket = serverSocket.accept();
                LOGGER.info("New client connection: {}", socket.getPort());
            } catch (IOException e) {
                throw new WakamitiException(e);
            }
            threadPool.submit(()-> launchLanguageServer(socket));
        }
    }


    private void launchLanguageServer(Socket socket) {
        try {
            LOGGER.info("Creating new server instance for connection {}", socket.getPort());
            var server = new WakamitiLanguageServer(baseIndex);
            var launcher = LSPLauncher.createServerLauncher(
                server,
                socket.getInputStream(),
                socket.getOutputStream()
            );
            server.connect(launcher.getRemoteProxy());
            FutureUtil.whenDone(
                launcher.startListening(),
                ()->LOGGER.info("Server instance for connection {} closed.", socket.getPort())
            );
        } catch (IOException e) {
            throw new WakamitiException(e.getMessage(),e);
        }

    }


    private void assertServerRunning() {
        if (serverSocket == null || !serverSocket.isBound() || serverSocket.isClosed()) {
            throw new IllegalStateException("Wakamiti LSP Server is not running");
        }
    }


    public int getPort() {
        assertServerRunning();
        return serverSocket.getLocalPort();
    }


    public InetAddress getAddress() {
        assertServerRunning();
        return serverSocket.getInetAddress();
    }


    public void close() throws IOException {
    	serverSocket.close();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy