如何使用原始Java连接apex(salesforce)语言服务器?

问题描述 投票:0回答:1

我有兴趣探索 Salesforce for Apex 的语言服务器。我对这个概念很陌生,想了解如何与之沟通。 因此,我正在寻求帮助来编写可以与 Salesforce 提供的 JAR 进行通信的 Java 代码。附上链接供参考。

我需要一个演示该过程的 Java 代码的工作示例。

Salesforce Apex 语言服务器

下载 JAR

提供示例的 Typescript 文件

java salesforce apex language-server-protocol
1个回答
0
投票

经过大量研究,我成功地与 Apex 语言服务器进行了通信。尽管代码并不完美并且存在需要优化的地方,但它目前适用于初始化服务器、发送文档进行分析以及检索完成或类型提示等基本任务。

package com.iishanto;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class LanguageServerRunner {

    private final String serverPath;
    private final ExecutorService executorService;
    private Process languageServerProcess;
    private BufferedWriter writer;

    public LanguageServerRunner(String serverPath) {
        this.serverPath = serverPath;
        this.executorService = Executors.newFixedThreadPool(3);
    }

    public void startServer() throws IOException {
        ProcessBuilder processBuilder = new ProcessBuilder(
                "java",
                "-Xms256m",
                "-Xmx512m",
                "-Ddebug.internal.errors=true",
                "-Ddebug.semantic.errors=true",
                "-Ddebug.completion.statistics=true",
                "-jar",
                serverPath);
        languageServerProcess = processBuilder.start();
        writer = new BufferedWriter(new OutputStreamWriter(languageServerProcess.getOutputStream()));
        handleServerOutput(languageServerProcess.getInputStream(), "Server Response");
        handleServerOutput(languageServerProcess.getErrorStream(), "Error");
    }

    private void handleServerOutput(InputStream inputStream, String label) {
        executorService.submit(() -> {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(label + ": " + line);
                    if (label.equals("Server Response") && line.startsWith("Content-Length:")) {
                        int contentLength = Integer.parseInt(line.substring("Content-Length:".length()).trim());
                        char[] content = new char[contentLength];
                        reader.read(content, 0, contentLength);
                        System.out.println("Server Response Body: " + new String(content));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    public void sendMessage(String message) throws IOException {
        String formattedMessage = "Content-Length: " + message.length() + "\r\n\r\n" + message;
        writer.write(formattedMessage);
        writer.flush();
    }

    public void sendInitializeMessage() throws IOException {
        String initRequest = """
            {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "initialize",
                "params": {
                    "processId": null,
                    "rootUri": "file:///C:/Users/Example/Desktop/Project",
                    "rootPath": "C:/Users/Example/Desktop/Project/",
                    "capabilities": {
                        "textDocument": {
                            "synchronization": {
                                "dynamicRegistration": true,
                                "willSave": true,
                                "willSaveWaitUntil": true,
                                "didSave": true
                            },
                            "completion": {
                                          "dynamicRegistration": true,
                                          "completionItem": {
                                            "snippetSupport": true,
                                            "commitCharactersSupport": true
                                          }
                                        }
                        },
                        "workspace": {
                            "applyEdit": true,
                            "workspaceEdit": {
                                "documentChanges": true
                            }
                        }
                    }
                }
            }
            """;
        sendMessage(initRequest);
    }

    public void sendDidOpenMessage(String fileUri, String languageId, int version, String text) throws IOException {
        String openRequest = """
            {
                "jsonrpc": "2.0",
                "method": "textDocument/didOpen",
                "params": {
                    "textDocument": {
                        "uri": "%s",
                        "languageId": "%s",
                        "version": %d,
                        "text": "%s"
                    }
                }
            }
            """.formatted(fileUri, languageId, version, text);
        sendMessage(openRequest);
    }

    public void sendTypeHintingMessage(String fileUri,String content,int line,int column) throws IOException {
        String message= """
                {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "textDocument/completion",
                    "params": {
                        "textDocument": {
                             "uri": "%s"
                        },
                        "position": {
                            "line": %d,
                            "character": %d
                        },
                        "context": {
                            "triggerKind": 1,
                            "triggerCharacter": "."
                        }
                    }
                }
                """.formatted(fileUri,line,column);
        System.out.println(message);
        sendMessage(message);
    }

    public void stopServer() throws InterruptedException {
        if (languageServerProcess != null) {
            int exitCode = languageServerProcess.waitFor();
            System.out.println("Language Server exited with code: " + exitCode);
        }
        executorService.shutdown();
    }

    public static void main(String[] args) {
        String serverPath = "C:\\Users\\Example\\Downloads\\apex-jorje-lsp.jar";
        String filePath = "C:\\Users\\Example\\Desktop\\Project\\force-app\\main\\default\\classes\\DynamicFieldFetcher.cls";

        try {
            LanguageServerRunner runner = new LanguageServerRunner(serverPath);
            runner.startServer();

            String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));

            runner.sendInitializeMessage();

            runner.sendDidOpenMessage(
                    "file:///C:/Users/Example/Desktop/Project/force-app/main/default/classes/DynamicFieldFetcher.cls",
                    "apex",
                    6,
                    fileContent
            );


            TimeUnit.MILLISECONDS.sleep(5000);

            runner.sendTypeHintingMessage(
                    "file:///C:/Users/Example/Desktop/Project/force-app/main/default/classes/DynamicFieldFetcher.cls"
                    ,fileContent,5,34);

            BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
            String inputLine;
            while ((inputLine = userInput.readLine()) != null) {
                runner.sendMessage(inputLine);
            }

            runner.stopServer();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.