Skip to content

Commit

Permalink
Issue 8721 - Update Libraries, etc. based on JDT notifications #8721 (#…
Browse files Browse the repository at this point in the history
…9650)

Added a listener for CLASSPATH change events that updates External Libraries nodes accordingly

Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
  • Loading branch information
vrubezhny authored and tsmaeder committed Oct 16, 2018
1 parent 87f175a commit 58b603b
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* 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:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.ide.project.node;

import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;

/** @author V. Rubezhny */
public class ProjectClasspathChangedEvent
extends GwtEvent<ProjectClasspathChangedEvent.ProjectClasspathChangedHandler> {

private String projectPath;

public interface ProjectClasspathChangedHandler extends EventHandler {
void onProjectClasspathChanged(ProjectClasspathChangedEvent event);
}

private static Type<ProjectClasspathChangedHandler> TYPE;

public static Type<ProjectClasspathChangedHandler> getType() {
if (TYPE == null) {
TYPE = new Type<>();
}
return TYPE;
}

public ProjectClasspathChangedEvent(String projectPath) {
this.projectPath = projectPath;
}

public String getProject() {
return projectPath;
}

@Override
public Type<ProjectClasspathChangedHandler> getAssociatedType() {
return TYPE;
}

/** {@inheritDoc} */
@Override
protected void dispatch(ProjectClasspathChangedHandler handler) {
handler.onProjectClasspathChanged(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.eclipse.che.ide.ext.java.client.JavaResources;
import org.eclipse.che.ide.ext.java.client.service.JavaLanguageExtensionServiceClient;
import org.eclipse.che.ide.ext.java.client.tree.JavaNodeFactory;
import org.eclipse.che.ide.project.node.ProjectClasspathChangedEvent;
import org.eclipse.che.ide.project.node.ProjectClasspathChangedEvent.ProjectClasspathChangedHandler;
import org.eclipse.che.ide.project.node.SyntheticNode;
import org.eclipse.che.ide.project.node.SyntheticNodeUpdateEvent;
import org.eclipse.che.ide.resource.Path;
Expand All @@ -40,7 +42,8 @@

/** @author Vlad Zhukovskiy */
@Beta
public class LibrariesNode extends SyntheticNode<Path> implements ResourceChangedHandler {
public class LibrariesNode extends SyntheticNode<Path>
implements ResourceChangedHandler, ProjectClasspathChangedHandler {

private final JavaNodeFactory nodeFactory;
private DtoFactory dtoFactory;
Expand All @@ -65,6 +68,7 @@ public LibrariesNode(
this.eventBus = eventBus;

eventBus.addHandler(ResourceChangedEvent.getType(), this);
eventBus.addHandler(ProjectClasspathChangedEvent.getType(), this);
}

@Override
Expand Down Expand Up @@ -112,6 +116,15 @@ public void onResourceChanged(ResourceChangedEvent event) {
}
}

@Override
public void onProjectClasspathChanged(ProjectClasspathChangedEvent event) {
final Path project = new Path(event.getProject());

if (getProject().equals(project)) {
eventBus.fireEvent(new SyntheticNodeUpdateEvent(LibrariesNode.this));
}
}

@Override
public Path getProject() {
return getData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ public final class Constants {
public static final String VALIDATE_RENAMED_NAME = "java/validateRenamedName";
public static final String GET_LINKED_MODEL = "java/getLinkedModel";

public static final String EXECUTE_CLIENT_COMMAND = "workspace/executeClientCommand";
public static final String EXECUTE_CLIENT_COMMAND_UNSUBSCRIBE =
"workspace/executeClientCommand/unsubscribe";
public static final String EXECUTE_CLIENT_COMMAND_SUBSCRIBE =
"workspace/executeClientCommand/subscribe";

private Constants() {
throw new UnsupportedOperationException("Unused constructor.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* 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:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.java.languageserver;

import static org.eclipse.che.ide.ext.java.shared.Constants.EXECUTE_CLIENT_COMMAND;
import static org.eclipse.che.ide.ext.java.shared.Constants.EXECUTE_CLIENT_COMMAND_SUBSCRIBE;
import static org.eclipse.che.ide.ext.java.shared.Constants.EXECUTE_CLIENT_COMMAND_UNSUBSCRIBE;

import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.core.jsonrpc.commons.RequestHandlerConfigurator;
import org.eclipse.che.api.core.jsonrpc.commons.RequestTransmitter;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls;
import org.eclipse.che.api.languageserver.server.dto.DtoServerImpls.ExecuteCommandParamsDto;
import org.eclipse.lsp4j.ExecuteCommandParams;

/** Transmits 'workspace/executeClientCommand' over the JSON-RPC */
@Singleton
public class ExecuteClientCommandJsonRpcTransmitter {
private final Set<String> endpointIds = new CopyOnWriteArraySet<>();

private final RequestTransmitter requestTransmitter;

@Inject
public ExecuteClientCommandJsonRpcTransmitter(RequestTransmitter requestTransmitter) {
this.requestTransmitter = requestTransmitter;
}

@Inject
private void subscribe(EventService eventService, RequestTransmitter requestTransmitter) {
eventService.subscribe(
event ->
endpointIds.forEach(
endpointId ->
requestTransmitter
.newRequest()
.endpointId(endpointId)
.methodName(EXECUTE_CLIENT_COMMAND)
.paramsAsDto(new ExecuteCommandParamsDto(event))
.sendAndSkipResult()),
ExecuteCommandParams.class);
}

@Inject
private void configureSubscribeHandler(RequestHandlerConfigurator requestHandler) {
requestHandler
.newConfiguration()
.methodName(EXECUTE_CLIENT_COMMAND_SUBSCRIBE)
.noParams()
.noResult()
.withConsumer(endpointIds::add);
}

@Inject
private void configureUnSubscribeHandler(RequestHandlerConfigurator requestHandler) {
requestHandler
.newConfiguration()
.methodName(EXECUTE_CLIENT_COMMAND_UNSUBSCRIBE)
.noParams()
.noResult()
.withConsumer(endpointIds::remove);
}

public CompletableFuture<Object> executeClientCommand(ExecuteCommandParams requestParams) {
ExecuteCommandParamsDto paramsDto =
(ExecuteCommandParamsDto) DtoServerImpls.makeDto(requestParams);

CompletableFuture<Object> result = new CompletableFuture<>();
for (String endpointId : endpointIds) {
requestTransmitter
.newRequest()
.endpointId(endpointId)
.methodName(EXECUTE_CLIENT_COMMAND)
.paramsAsDto(paramsDto)
.sendAndSkipResult();
}
result.complete(null);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
*/
package org.eclipse.che.plugin.java.languageserver;

import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;

public interface JavaLanguageClient {
/**
Expand All @@ -28,4 +31,7 @@ public interface JavaLanguageClient {
*/
@JsonNotification("language/progressReport")
void sendProgressReport(ProgressReport report);

@JsonRequest("workspace/executeClientCommand")
CompletableFuture<Object> executeClientCommand(ExecuteCommandParams params);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
*/
package org.eclipse.che.plugin.java.languageserver;

import static org.eclipse.che.api.languageserver.LanguageServiceUtils.removePrefixUri;
import static org.eclipse.che.api.languageserver.util.JsonUtil.convertToJson;
import static org.eclipse.che.jdt.ls.extension.api.Commands.CLIENT_UPDATE_PROJECTS_CLASSPATH;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.InputStream;
Expand All @@ -18,14 +22,18 @@
import java.lang.reflect.Proxy;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.eclipse.che.api.languageserver.LanguageServerConfig;
import org.eclipse.che.api.languageserver.ProcessCommunicationProvider;
import org.eclipse.che.api.languageserver.service.FileContentAccess;
import org.eclipse.che.api.languageserver.util.DynamicWrapper;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageServer;
Expand All @@ -43,10 +51,14 @@ public class JavaLanguageServerLauncher implements LanguageServerConfig {

private final Path launchScript;
private ProcessorJsonRpcCommunication processorJsonRpcCommunication;
private ExecuteClientCommandJsonRpcTransmitter executeCliendCommandTransmitter;

@Inject
public JavaLanguageServerLauncher(ProcessorJsonRpcCommunication processorJsonRpcCommunication) {
public JavaLanguageServerLauncher(
ProcessorJsonRpcCommunication processorJsonRpcCommunication,
ExecuteClientCommandJsonRpcTransmitter executeCliendCommandTransmitter) {
this.processorJsonRpcCommunication = processorJsonRpcCommunication;
this.executeCliendCommandTransmitter = executeCliendCommandTransmitter;
launchScript = Paths.get(System.getenv("HOME"), "che/ls-java/launch.sh");
}

Expand All @@ -64,6 +76,21 @@ public void sendProgressReport(ProgressReport report) {
processorJsonRpcCommunication.sendProgressNotification(report);
}

public CompletableFuture<Object> executeClientCommand(ExecuteCommandParams params) {
return executeCliendCommandTransmitter.executeClientCommand(convertParams(params));
}

private ExecuteCommandParams convertParams(ExecuteCommandParams params) {
if (CLIENT_UPDATE_PROJECTS_CLASSPATH.equals(params.getCommand())) {
List<Object> fixedPathList = new ArrayList<>();
for (Object uri : params.getArguments()) {
fixedPathList.add(removePrefixUri(convertToJson(uri).getAsString()));
}
params.setArguments(fixedPathList);
}
return params;
}

@Override
public RegexProvider getRegexpProvider() {
return new RegexProvider() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.eclipse.che.plugin.languageserver.ide.navigation.workspace.FindSymbolAction;
import org.eclipse.che.plugin.languageserver.ide.registry.LanguageServerRegistry;
import org.eclipse.che.plugin.languageserver.ide.rename.LSRenameAction;
import org.eclipse.che.plugin.languageserver.ide.service.ExecuteClientCommandReceiver;
import org.eclipse.che.plugin.languageserver.ide.service.PublishDiagnosticsReceiver;
import org.eclipse.che.plugin.languageserver.ide.service.ShowMessageJsonRpcReceiver;
import org.eclipse.che.plugin.languageserver.ide.service.TextDocumentServiceClient;
Expand All @@ -63,7 +64,8 @@ public LanguageServerExtension(
EventBus eventBus,
AppContext appContext,
ShowMessageJsonRpcReceiver showMessageJsonRpcReceiver,
PublishDiagnosticsReceiver publishDiagnosticsReceiver) {
PublishDiagnosticsReceiver publishDiagnosticsReceiver,
ExecuteClientCommandReceiver executeClientCommandReceiver) {
eventBus.addHandler(
WsAgentServerRunningEvent.TYPE,
e -> {
Expand All @@ -73,6 +75,7 @@ public LanguageServerExtension(
defaultHoverProviderInitializer.initialize();
showMessageJsonRpcReceiver.subscribe();
publishDiagnosticsReceiver.subscribe();
executeClientCommandReceiver.subscribe();
});

if (appContext.getWorkspace().getStatus() == RUNNING) {
Expand All @@ -82,6 +85,7 @@ public LanguageServerExtension(
defaultHoverProviderInitializer.initialize();
showMessageJsonRpcReceiver.subscribe();
publishDiagnosticsReceiver.subscribe();
executeClientCommandReceiver.subscribe();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.che.plugin.languageserver.ide.editor.signature.LanguageServerSignatureHelpFactory;
import org.eclipse.che.plugin.languageserver.ide.location.OpenLocationPresenterFactory;
import org.eclipse.che.plugin.languageserver.ide.rename.node.RenameNodeFactory;
import org.eclipse.che.plugin.languageserver.ide.service.ExecuteClientCommandReceiver;
import org.eclipse.che.plugin.languageserver.ide.service.PublishDiagnosticsReceiver;
import org.eclipse.che.plugin.languageserver.ide.service.ShowMessageJsonRpcReceiver;

Expand All @@ -52,6 +53,7 @@ protected void configure() {

bind(PublishDiagnosticsReceiver.class).asEagerSingleton();
bind(ShowMessageJsonRpcReceiver.class).asEagerSingleton();
bind(ExecuteClientCommandReceiver.class).asEagerSingleton();

GinMultibinder.newSetBinder(binder(), LanguageDescription.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* 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:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.languageserver.ide.service;

import com.google.gwt.json.client.JSONString;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.web.bindery.event.shared.EventBus;
import org.eclipse.che.ide.project.node.ProjectClasspathChangedEvent;
import org.eclipse.lsp4j.ExecuteCommandParams;

/**
* A processor for incoming <code>workspace/ClasspathChanged</code> notifications sent by a language
* server.
*
* @author V. Rubezhny
*/
@Singleton
public class ExecuteClientCommandProcessor {
private static final String CLIENT_UPDATE_PROJECTS_CLASSPATH =
"che.jdt.ls.extension.workspace.clientUpdateProjectsClasspath";

private EventBus eventBus;

@Inject
public ExecuteClientCommandProcessor(EventBus eventBus) {
this.eventBus = eventBus;
}

public void execute(ExecuteCommandParams params) {
if (CLIENT_UPDATE_PROJECTS_CLASSPATH.equals(params.getCommand())) {
for (Object project : params.getArguments()) {
eventBus.fireEvent(new ProjectClasspathChangedEvent(stringValue(project)));
}
}
}

private String stringValue(Object value) {
return value instanceof JSONString ? ((JSONString) value).stringValue() : String.valueOf(value);
}
}
Loading

0 comments on commit 58b603b

Please sign in to comment.