/*******************************************************************************
* 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.csharp.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.shared.model.LanguageDescription;
import org.eclipse.che.commons.lang.IoUtil;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageServer;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import static java.util.Arrays.asList;
/**
* @author Evgen Vidolob
*/
@Singleton
public class CSharpLanguageServerLauncher extends LanguageServerLauncherTemplate {
private static final String LANGUAGE_ID = "csharp";
private static final String[] EXTENSIONS = new String[]{"cs", "csx"};
private static final String[] MIME_TYPES = new String[]{"text/x-csharp"};
private static final LanguageDescription description;
private final Path launchScript;
@Inject
public CSharpLanguageServerLauncher() {
launchScript = Paths.get(System.getenv("HOME"), "che/ls-csharp/launch.sh");
}
@Override
protected Process startLanguageServerProcess(String projectPath) throws LanguageServerException {
restoreDependencies(projectPath);
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 CSharp language server", e);
}
}
private void restoreDependencies(String projectPath) throws LanguageServerException {
ProcessBuilder processBuilder = new ProcessBuilder("dotnet", "restore");
processBuilder.directory(new File(projectPath));
try {
Process process = processBuilder.start();
int resultCode = process.waitFor();
if (resultCode != 0) {
String err = IoUtil.readStream(process.getErrorStream());
String in = IoUtil.readStream(process.getInputStream());
throw new LanguageServerException("Can't restore dependencies. Error: " + err + ". Output: " + in);
}
} catch (IOException | InterruptedException e) {
throw new LanguageServerException("Can't start CSharp language server", e);
}
}
@Override
protected LanguageServer connectToLanguageServer(final Process languageServerProcess, LanguageClient client) {
Launcher<LanguageServer> launcher = Launcher.createLauncher(client, LanguageServer.class, languageServerProcess.getInputStream(),
languageServerProcess.getOutputStream());
launcher.startListening();
return launcher.getRemoteProxy();
}
@Override
public LanguageDescription getLanguageDescription() {
return description;
}
@Override
public boolean isAbleToLaunch() {
return Files.exists(launchScript);
}
static {
description = new LanguageDescription();
description.setFileExtensions(asList(EXTENSIONS));
description.setLanguageId(LANGUAGE_ID);
description.setMimeTypes(Arrays.asList(MIME_TYPES));
}
}