diff --git a/agents/pom.xml b/agents/pom.xml index 097c929b8bd..9b5834e75ba 100644 --- a/agents/pom.xml +++ b/agents/pom.xml @@ -38,4 +38,12 @@ ls-typescript ls-csharp + + + test-ls + + test-ls + + + diff --git a/agents/test-ls/pom.xml b/agents/test-ls/pom.xml new file mode 100644 index 00000000000..2ee904f12df --- /dev/null +++ b/agents/test-ls/pom.xml @@ -0,0 +1,41 @@ + + + + 4.0.0 + + che-agents-parent + org.eclipse.che + 5.16.0-SNAPSHOT + + test-ls-agent + Test Language Server Agent + + + com.google.inject + guice + + + com.google.inject.extensions + guice-multibindings + + + org.eclipse.che.core + che-core-api-agent-shared + + + org.eclipse.che.core + che-core-commons-inject + + + diff --git a/agents/test-ls/src/main/java/org/eclipse/che/api/agent/TestLSAgent.java b/agents/test-ls/src/main/java/org/eclipse/che/api/agent/TestLSAgent.java new file mode 100644 index 00000000000..4d1d500b11b --- /dev/null +++ b/agents/test-ls/src/main/java/org/eclipse/che/api/agent/TestLSAgent.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ + +package org.eclipse.che.api.agent; import com.google.inject.Inject; +import com.google.inject.Singleton; + +import org.eclipse.che.api.agent.shared.model.Agent; +import org.eclipse.che.api.agent.shared.model.impl.BasicAgent; + +import java.io.IOException; + +/** + * Test Language server agent. + * + * @see Agent + * + */ +@Singleton +public class TestLSAgent extends BasicAgent { + private static final String AGENT_DESCRIPTOR = "org.eclipse.che.test.ls.json"; + private static final String AGENT_SCRIPT = "org.eclipse.che.test.ls.script.sh"; + + @Inject + public TestLSAgent() throws IOException { + super(AGENT_DESCRIPTOR, AGENT_SCRIPT); + } +} diff --git a/agents/test-ls/src/main/java/org/eclipse/che/api/agent/TestLSModule.java b/agents/test-ls/src/main/java/org/eclipse/che/api/agent/TestLSModule.java new file mode 100644 index 00000000000..1ec8ca7ad47 --- /dev/null +++ b/agents/test-ls/src/main/java/org/eclipse/che/api/agent/TestLSModule.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ + +package org.eclipse.che.api.agent; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; + +import org.eclipse.che.api.agent.shared.model.Agent; +import org.eclipse.che.inject.DynaModule; + +/** + * + */ +@DynaModule +public class TestLSModule extends AbstractModule { + @Override + protected void configure() { + Multibinder agents = Multibinder.newSetBinder(binder(), Agent.class); + agents.addBinding().to(TestLSAgent.class); + } +} diff --git a/agents/test-ls/src/main/resources/org.eclipse.che.test.ls.json b/agents/test-ls/src/main/resources/org.eclipse.che.test.ls.json new file mode 100644 index 00000000000..f23c1acc3bf --- /dev/null +++ b/agents/test-ls/src/main/resources/org.eclipse.che.test.ls.json @@ -0,0 +1,7 @@ +{ + "id": "org.eclipse.che.test.ls", + "name": "Simple Test language server", + "description": "Test LS", + "dependencies": [], + "properties": {} +} diff --git a/agents/test-ls/src/main/resources/org.eclipse.che.test.ls.script.sh b/agents/test-ls/src/main/resources/org.eclipse.che.test.ls.script.sh new file mode 100644 index 00000000000..4d7889219a0 --- /dev/null +++ b/agents/test-ls/src/main/resources/org.eclipse.che.test.ls.script.sh @@ -0,0 +1,170 @@ +# +# Copyright (c) 2012-2017 Codenvy, S.A. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Codenvy, S.A. - initial API and implementation +# + +unset PACKAGES +unset SUDO +command -v tar >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" tar"; } +command -v curl >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" curl"; } +test "$(id -u)" = 0 || SUDO="sudo -E" + +AGENT_BINARIES_URI=https://codenvy.com/update/repository/public/download/org.eclipse.che.ls.test.binaries +CHE_DIR=$HOME/che +LS_DIR=${CHE_DIR}/test-ls +LS_LAUNCHER=${LS_DIR}/launch.sh + +if [ -f /etc/centos-release ]; then + FILE="/etc/centos-release" + LINUX_TYPE=$(cat $FILE | awk '{print $1}') + elif [ -f /etc/redhat-release ]; then + FILE="/etc/redhat-release" + LINUX_TYPE=$(cat $FILE | cut -c 1-8) + else + FILE="/etc/os-release" + LINUX_TYPE=$(cat $FILE | grep ^ID= | tr '[:upper:]' '[:lower:]') + LINUX_VERSION=$(cat $FILE | grep ^VERSION_ID=) +fi + +MACHINE_TYPE=$(uname -m) + +mkdir -p ${CHE_DIR} +mkdir -p ${LS_DIR} + +######################## +### Install packages ### +######################## + +# Red Hat Enterprise Linux 7 +############################ +if echo ${LINUX_TYPE} | grep -qi "rhel"; then + test "${PACKAGES}" = "" || { + ${SUDO} yum install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} yum -y install nodejs; + } + +# Red Hat Enterprise Linux 6 +############################ +elif echo ${LINUX_TYPE} | grep -qi "Red Hat"; then + test "${PACKAGES}" = "" || { + ${SUDO} yum install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} yum -y install nodejs; + } + + +# Ubuntu 14.04 16.04 / Linux Mint 17 +#################################### +elif echo ${LINUX_TYPE} | grep -qi "ubuntu"; then + test "${PACKAGES}" = "" || { + ${SUDO} apt-get update; + ${SUDO} apt-get -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + { + curl -sL https://deb.nodesource.com/setup_6.x | ${SUDO} bash -; + }; + + ${SUDO} apt-get update; + ${SUDO} apt-get install -y nodejs; + } + + +# Debian 8 +########## +elif echo ${LINUX_TYPE} | grep -qi "debian"; then + test "${PACKAGES}" = "" || { + ${SUDO} apt-get update; + ${SUDO} apt-get -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + { + curl -sL https://deb.nodesource.com/setup_6.x | ${SUDO} bash -; + }; + + ${SUDO} apt-get update; + ${SUDO} apt-get install -y nodejs; + } + +# Fedora 23 +########### +elif echo ${LINUX_TYPE} | grep -qi "fedora"; then + command -v ps >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" procps-ng"; } + test "${PACKAGES}" = "" || { + ${SUDO} dnf -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} dnf -y install nodejs; + } + + +# CentOS 7.1 & Oracle Linux 7.1 +############################### +elif echo ${LINUX_TYPE} | grep -qi "centos"; then + test "${PACKAGES}" = "" || { + ${SUDO} yum -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} yum -y install nodejs; + } + +# openSUSE 13.2 +############### +elif echo ${LINUX_TYPE} | grep -qi "opensuse"; then + test "${PACKAGES}" = "" || { + ${SUDO} zypper install -y ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + ${SUDO} zypper ar http://download.opensuse.org/repositories/devel:/languages:/nodejs/openSUSE_13.1/ Node.js + ${SUDO} zypper in nodejs + } + +# Alpine 3.3 +############ +elif echo ${LINUX_TYPE} | grep -qi "alpine"; then + test "${PACKAGES}" = "" || { + ${SUDO} apk update + ${SUDO} apk add ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + ${SUDO} apk update + ${SUDO} apk add nodejs; + } + +else + >&2 echo "Unrecognized Linux Type" + >&2 cat $FILE + exit 1 +fi + + +####################### +### Install Test LS ### +####################### + +curl -s ${AGENT_BINARIES_URI} | tar xzf - -C ${LS_DIR} + +touch ${LS_LAUNCHER} +chmod +x ${LS_LAUNCHER} +echo "${LS_DIR}/test-ls/server.sh" > ${LS_LAUNCHER} diff --git a/assembly/assembly-wsagent-war/pom.xml b/assembly/assembly-wsagent-war/pom.xml index c5c4a2ce9d5..f55824e7335 100644 --- a/assembly/assembly-wsagent-war/pom.xml +++ b/assembly/assembly-wsagent-war/pom.xml @@ -162,4 +162,15 @@ + + + test-ls + + + org.eclipse.che.plugin + che-plugin-test-ls-server + + + + diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index 8e1c3c38d62..2ffd31f3819 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -340,4 +340,15 @@ + + + test-ls + + + org.eclipse.che + test-ls-agent + + + + diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/GsonJsonRpcMarshaller.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/GsonJsonRpcMarshaller.java index 3660f8c9d5e..f5805f7dedd 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/GsonJsonRpcMarshaller.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/GsonJsonRpcMarshaller.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.che.api.core.jsonrpc.impl; +import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonNull; @@ -33,10 +34,12 @@ public class GsonJsonRpcMarshaller implements JsonRpcMarshaller { private final JsonParser jsonParser; + private final Gson gson; @Inject - public GsonJsonRpcMarshaller(JsonParser jsonParser) { + public GsonJsonRpcMarshaller(JsonParser jsonParser, Gson gson) { this.jsonParser = jsonParser; + this.gson = gson; } @Override @@ -164,7 +167,7 @@ private JsonElement getJsonElement(Object param) { try { return jsonParser.parse(DtoFactory.getInstance().toJson(param)); } catch (IllegalArgumentException e){ - return jsonParser.parse(param.toString()); + return gson.toJsonTree(param); } } } diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/JsonRpcModule.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/JsonRpcModule.java index 9e382f68b60..6b6526dfd37 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/JsonRpcModule.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/jsonrpc/impl/JsonRpcModule.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.che.api.core.jsonrpc.impl; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonParser; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -23,6 +25,7 @@ import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcUnmarshaller; import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator; import org.eclipse.che.api.core.jsonrpc.commons.TimeoutActionRunner; +import org.eclipse.che.dto.server.DtoFactory; import javax.inject.Singleton; @@ -46,4 +49,10 @@ protected void configure() { public JsonParser jsonParser() { return new JsonParser(); } + + @Provides + @Singleton + protected Gson gson() { + return DtoFactory.getInstance().getGson(); + } } diff --git a/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/window/dialog/MessageDialogFooter.ui.xml b/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/window/dialog/MessageDialogFooter.ui.xml index eafbd2aad4d..75ae486d873 100644 --- a/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/window/dialog/MessageDialogFooter.ui.xml +++ b/plugins/plugin-languageserver/che-plugin-languageserver-ide/src/main/java/org/eclipse/che/plugin/languageserver/ide/window/dialog/MessageDialogFooter.ui.xml @@ -1,14 +1,16 @@ + + Copyright (c) 2012-2017 Codenvy, S.A. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Contributors: + Codenvy, S.A. - initial API and implementation + +--> @@ -43,7 +45,5 @@ - - \ No newline at end of file diff --git a/plugins/plugin-languageserver/che-plugin-test-ls/pom.xml b/plugins/plugin-languageserver/che-plugin-test-ls/pom.xml new file mode 100644 index 00000000000..44b37c8af7f --- /dev/null +++ b/plugins/plugin-languageserver/che-plugin-test-ls/pom.xml @@ -0,0 +1,53 @@ + + + + 4.0.0 + + che-plugin-languageserver-parent + org.eclipse.che.plugin + 5.16.0-SNAPSHOT + + che-plugin-test-ls-server + Che Plugin :: TEST LS :: Extension Server + + + com.google.inject + guice + + + com.google.inject.extensions + guice-multibindings + + + org.eclipse.che.core + che-core-api-languageserver + + + org.eclipse.che.core + che-core-api-languageserver-shared + + + org.eclipse.che.core + che-core-commons-inject + + + org.eclipse.lsp4j + org.eclipse.lsp4j + + + org.eclipse.lsp4j + org.eclipse.lsp4j.jsonrpc + + + diff --git a/plugins/plugin-languageserver/che-plugin-test-ls/src/main/java/org/eclipse/che/plugin/test/ls/inject/TestLSModule.java b/plugins/plugin-languageserver/che-plugin-test-ls/src/main/java/org/eclipse/che/plugin/test/ls/inject/TestLSModule.java new file mode 100644 index 00000000000..881b5e7c490 --- /dev/null +++ b/plugins/plugin-languageserver/che-plugin-test-ls/src/main/java/org/eclipse/che/plugin/test/ls/inject/TestLSModule.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.plugin.test.ls.inject; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; + +import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher; +import org.eclipse.che.api.languageserver.shared.model.LanguageDescription; +import org.eclipse.che.inject.DynaModule; +import org.eclipse.che.plugin.test.ls.languageserver.TestLanguageServerLauncher; + +import static java.util.Arrays.asList; + +/** + * + */ +@DynaModule +public class TestLSModule extends AbstractModule { + public static final String LANGUAGE_ID = "testLS"; + private static final String[] EXTENSIONS = new String[]{"test"}; + private static final String MIME_TYPE = "application/ls-test"; + + @Override + protected void configure() { + Multibinder.newSetBinder(binder(), LanguageServerLauncher.class).addBinding().to(TestLanguageServerLauncher.class); + LanguageDescription description = new LanguageDescription(); + description.setFileExtensions(asList(EXTENSIONS)); + description.setLanguageId(LANGUAGE_ID); + description.setMimeType(MIME_TYPE); + Multibinder.newSetBinder(binder(), LanguageDescription.class).addBinding().toInstance(description); + } +} diff --git a/plugins/plugin-languageserver/che-plugin-test-ls/src/main/java/org/eclipse/che/plugin/test/ls/languageserver/TestLanguageServerLauncher.java b/plugins/plugin-languageserver/che-plugin-test-ls/src/main/java/org/eclipse/che/plugin/test/ls/languageserver/TestLanguageServerLauncher.java new file mode 100644 index 00000000000..25b8f328406 --- /dev/null +++ b/plugins/plugin-languageserver/che-plugin-test-ls/src/main/java/org/eclipse/che/plugin/test/ls/languageserver/TestLanguageServerLauncher.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.plugin.test.ls.languageserver; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import org.eclipse.che.api.languageserver.exception.LanguageServerException; +import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncherTemplate; +import org.eclipse.che.api.languageserver.registry.DocumentFilter; +import org.eclipse.che.api.languageserver.registry.LanguageServerDescription; +import org.eclipse.che.plugin.test.ls.inject.TestLSModule; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.services.LanguageClient; +import org.eclipse.lsp4j.services.LanguageServer; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; + + +/** + * Launcher for simple test Language server + * + * @author Evgen Vidolob + */ +@Singleton +public class TestLanguageServerLauncher extends LanguageServerLauncherTemplate { + private static final LanguageServerDescription DESCRIPTION = createServerDescription(); + + private final Path launchScript; + + @Inject + public TestLanguageServerLauncher() { + launchScript = Paths.get(System.getenv("HOME"), "che/test-ls/launch.sh"); + } + + private static LanguageServerDescription createServerDescription() { + return new LanguageServerDescription("org.eclipse.che.plugin.test.languageserver", + null, + Collections.singletonList(new DocumentFilter(TestLSModule.LANGUAGE_ID, null, null))); + } + + @Override + public boolean isAbleToLaunch() { + return Files.exists(launchScript); + } + + protected LanguageServer connectToLanguageServer(final Process languageServerProcess, LanguageClient client) { + Launcher launcher = Launcher.createLauncher(client, LanguageServer.class, + languageServerProcess.getInputStream(), + languageServerProcess.getOutputStream()); + launcher.startListening(); + return launcher.getRemoteProxy(); + } + + protected Process startLanguageServerProcess(String projectPath) throws LanguageServerException { + ProcessBuilder processBuilder = new ProcessBuilder(launchScript.toString()); + processBuilder.redirectInput(ProcessBuilder.Redirect.PIPE); + processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE); + try { + return processBuilder.start(); + } catch (IOException e) { + throw new LanguageServerException("Can't start Test language server", e); + } + } + + public LanguageServerDescription getDescription() { + return DESCRIPTION; + } +} diff --git a/plugins/plugin-languageserver/pom.xml b/plugins/plugin-languageserver/pom.xml index 06b92060c8b..21a6c9067ad 100644 --- a/plugins/plugin-languageserver/pom.xml +++ b/plugins/plugin-languageserver/pom.xml @@ -25,4 +25,12 @@ che-plugin-languageserver-ide + + + test-ls + + che-plugin-test-ls + + + diff --git a/plugins/plugin-maven/maven-server/maven-server-impl/pom.xml b/plugins/plugin-maven/maven-server/maven-server-impl/pom.xml index b16284d22b0..145b3acc476 100644 --- a/plugins/plugin-maven/maven-server/maven-server-impl/pom.xml +++ b/plugins/plugin-maven/maven-server/maven-server-impl/pom.xml @@ -246,31 +246,31 @@ - integration - - false - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - integration-test - verify - - - - - - **/maven/server/** - - - - - - + integration + + false + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + **/maven/server/** + + + + + + diff --git a/pom.xml b/pom.xml index 74fb9c48a86..b068bdcd1c5 100644 --- a/pom.xml +++ b/pom.xml @@ -560,6 +560,12 @@ che-terminal-client ${che.lib.version} + + org.eclipse.che.lib + che-test-ls + ${che.lib.version} + tar.gz + org.eclipse.che.lib che-tomcat8-slf4j-logback @@ -1191,5 +1197,22 @@ true + + test-ls + + + + org.eclipse.che + test-ls-agent + ${che.version} + + + org.eclipse.che.plugin + che-plugin-test-ls-server + ${che.version} + + + + diff --git a/wsagent/che-core-api-languageserver/pom.xml b/wsagent/che-core-api-languageserver/pom.xml index 2f1f8137c0a..2f7fcedceba 100644 --- a/wsagent/che-core-api-languageserver/pom.xml +++ b/wsagent/che-core-api-languageserver/pom.xml @@ -37,6 +37,10 @@ com.google.inject guice + + com.google.inject.extensions + guice-assistedinject + com.google.inject.extensions guice-multibindings @@ -90,6 +94,13 @@ logback-classic test + + org.eclipse.che.lib + che-test-ls + ${che.lib.version} + tar.gz + test + org.hamcrest hamcrest-core @@ -132,6 +143,31 @@ + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-jar-lib-for-test + process-resources + + unpack + + + + + org.eclipse.che.lib + che-test-ls + ${project.version} + tar.gz + ${project.build.testOutputDirectory}/ls + test-ls.tar.gz + + + + + + com.mycila license-maven-plugin diff --git a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/ShowMessageJsonRpcTransmitter.java b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/ShowMessageJsonRpcTransmitter.java index 24f48f69731..3a86b50c309 100644 --- a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/ShowMessageJsonRpcTransmitter.java +++ b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/messager/ShowMessageJsonRpcTransmitter.java @@ -91,19 +91,25 @@ public CompletableFuture sendShowMessageRequest(ShowMessageRe if (showMessageRequestEndpointIds.isEmpty()) { result.complete(null); } - if (showMessageRequestEndpointIds.size() > 1) { - result.completeExceptionally(new Exception("Can't send show message request, too meany clients")); - } else { - String endpoint = showMessageRequestEndpointIds.iterator().next(); +// if (showMessageRequestEndpointIds.size() > 1) { +// result.completeExceptionally(new Exception("Can't send show message request, too meany clients")); +// } else { + for (String endpointId : endpointIds) { requestTransmitter.newRequest() - .endpointId(endpoint) + .endpointId(endpointId) .methodName("window/showMessageRequest") .paramsAsDto(requestParams) .sendAndReceiveResultAsDto(MessageActionItem.class) - .onSuccess(result::complete) + .onSuccess(actionItem -> { + if(!result.isDone()){ + result.complete(actionItem); + } + }) .onFailure(jsonRpcError -> result.completeExceptionally(new Exception(jsonRpcError.getMessage()))); } +// } + return result; } } diff --git a/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/LocalTestLSLauncher.java b/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/LocalTestLSLauncher.java new file mode 100644 index 00000000000..2c2626067eb --- /dev/null +++ b/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/LocalTestLSLauncher.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ + +package org.eclipse.che.api.languageserver; + +import org.eclipse.che.api.languageserver.exception.LanguageServerException; +import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncherTemplate; +import org.eclipse.che.api.languageserver.registry.LanguageServerDescription; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.services.LanguageClient; +import org.eclipse.lsp4j.services.LanguageServer; + +import java.io.IOException; +import java.util.List; + +/** + * + */ +public class LocalTestLSLauncher extends LanguageServerLauncherTemplate{ + + private final LanguageServerDescription description; + private final List command; + + public LocalTestLSLauncher(List command, LanguageServerDescription description) { + this.command = command; + this.description = description; + } + + @Override + protected Process startLanguageServerProcess(String projectPath) throws LanguageServerException { + ProcessBuilder processBuilder = new ProcessBuilder(command); + processBuilder.redirectInput(ProcessBuilder.Redirect.PIPE); + processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE); + try { + return processBuilder.start(); + } catch (IOException e) { + throw new LanguageServerException("Can't start TypeScript language server", e); + } + } + + @Override + protected LanguageServer connectToLanguageServer(Process languageServerProcess, LanguageClient client) throws LanguageServerException { + Launcher launcher = Launcher.createLauncher(client, LanguageServer.class, languageServerProcess.getInputStream(), + languageServerProcess.getOutputStream()); + launcher.startListening(); + return launcher.getRemoteProxy(); + } + + @Override + public LanguageServerDescription getDescription() { + return description; + } + + @Override + public boolean isAbleToLaunch() { + return true; + } +} diff --git a/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/ShowMessageRequestTest.java b/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/ShowMessageRequestTest.java new file mode 100644 index 00000000000..14aa295effe --- /dev/null +++ b/wsagent/che-core-api-languageserver/src/test/java/org/eclipse/che/api/languageserver/ShowMessageRequestTest.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2012-2017 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ + +package org.eclipse.che.api.languageserver; + +import org.eclipse.che.api.core.notification.EventService; +import org.eclipse.che.api.languageserver.messager.ShowMessageJsonRpcTransmitter; +import org.eclipse.che.api.languageserver.registry.CheLanguageClient; +import org.eclipse.che.api.languageserver.registry.LanguageServerDescription; +import org.eclipse.che.api.languageserver.registry.ServerInitializerImpl; +import org.eclipse.che.commons.lang.Pair; +import org.eclipse.lsp4j.InitializeResult; +import org.eclipse.lsp4j.MessageActionItem; +import org.eclipse.lsp4j.MessageType; +import org.eclipse.lsp4j.ShowMessageRequestParams; +import org.eclipse.lsp4j.services.LanguageServer; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.testng.MockitoTestNGListener; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +/** + * + */ +@Listeners(MockitoTestNGListener.class) +public class ShowMessageRequestTest { + + private LocalTestLSLauncher launcher; + + @Mock + private EventService eventService; + + @Mock + private ShowMessageJsonRpcTransmitter transmitter; + private LanguageServer server; + + @BeforeMethod + public void setUp() throws Exception { + List command = new ArrayList<>(); + command.add(ShowMessageRequestTest.class.getResource("/ls").getFile() + "/test-ls/server.sh"); + launcher = + new LocalTestLSLauncher(command, + new LanguageServerDescription("foo", Collections.singletonList("aaa"), Collections.emptyList())); + + } + + @AfterMethod + public void tearDown() throws Exception { + if (server != null) { + server.shutdown(); + server.exit(); + } + } + + @Test + public void testName() throws Exception { + CompletableFuture future = new CompletableFuture<>(); + when(transmitter.sendShowMessageRequest(any())).thenReturn(future); + + ServerInitializerImpl initializer = new ServerInitializerImpl(); + CheLanguageClient client = new CheLanguageClient(eventService, transmitter, "id"); + CompletableFuture> initialize = initializer.initialize(launcher, client, "/tmp"); + Pair resultPair = initialize.get(); + server = resultPair.first; + Thread.sleep(1200); + ArgumentCaptor captor = ArgumentCaptor.forClass(ShowMessageRequestParams.class); + verify(transmitter).sendShowMessageRequest(captor.capture()); + + ShowMessageRequestParams value = captor.getValue(); + assertNotNull(value); + assertEquals(value.getType(), MessageType.Error); + assertEquals(value.getMessage(), "Error Message!!!!"); + } + +}