Skip to content

Commit

Permalink
GLSP-1117: Remove need for explicit definition of client actions
Browse files Browse the repository at this point in the history
Refactor the base GLSP protocol to allow the client to tell the server which actions it is going to handle i.e. which actions should be forwarded to the client
- Add `clientActions` array to `InitializeClientSessionParams`. This means the client now has to pass the action kinds it wants to handle as part of the initalize request
- Refactor `ClientSessionManager` API directly use the `InitializeClientSessionParams` object for creating new sessions. This means that the `ClientSessionManager` can also access the generic `args` properties that might have been passed with the initialize request.
- Replace `ClientActionHandler` with `ClientActionForwader` a separate component that is not part of the server-side action handlers. 
- Remove `configureClientActions` method from `DiagramModule` as the explicit configuration is no longer needed
- Refactor `ClientIdModule` to `ClietnSessionModule` responsible for injection session specific configuration like the clientId and the clientActions

Part of eclipse-glsp/glsp/issues/1117
  • Loading branch information
tortmayr committed Sep 14, 2023
1 parent debdc7b commit 525dd82
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 247 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2019-2021 EclipseSource and others.
* Copyright (c) 2019-2023 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -15,6 +15,8 @@
********************************************************************************/
package org.eclipse.glsp.server.actions;

import org.eclipse.glsp.server.protocol.GLSPServer;

/**
* Java-implementation of the `Action` interface. An action is a declarative description of a behavior that
* shall be
Expand All @@ -31,13 +33,24 @@ public abstract class Action {
*/
private final String kind;

/**
* Optional boolean flag that marks actions that have
* been received from the client. Is set automatically by the {@link GLSPServer}
* for every received action.
*/
private boolean receivedFromClient;

public Action(final String kind) {
super();
this.kind = kind;
}

public String getKind() { return kind; }

public boolean isReceivedFromClient() { return receivedFromClient; }

public void setReceivedFromClient(final boolean receivedFromClient) { this.receivedFromClient = receivedFromClient; }

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2019-2021 EclipseSource and others.
* Copyright (c) 2019-2023 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -25,17 +25,6 @@
*/
public interface ActionRegistry extends Registry<String, Map<String, Class<? extends Action>>> {

/**
* Registers an action for a diagramType.
*
* @param diagramType The diagramType for which the action is registered.
* @param actionKind The actionKind of the action to be registered.
* @param action The action to be registered.
* @param isServerAction This flag indicates if the given action is handled by the server.
* @return A boolean flag that indicates if the registration was successful.
*/
boolean register(String diagramType, String actionKind, Class<? extends Action> action, boolean isServerAction);

/**
* Registers a server handled action for a diagramType.
*
Expand All @@ -44,9 +33,7 @@ public interface ActionRegistry extends Registry<String, Map<String, Class<? ext
* @param action The action to be registered.
* @return A boolean flag that indicates if the registration was successful.
*/
default boolean register(final String diagramType, final String actionKind, final Class<? extends Action> action) {
return register(diagramType, actionKind, action, true);
}
boolean register(String diagramType, String actionKind, Class<? extends Action> action);

/**
* Registers a set of server handled actions for a diagramType.
Expand All @@ -56,34 +43,21 @@ default boolean register(final String diagramType, final String actionKind, fina
* @return A boolean flag that indicates if the registration was successful.
*/
@Override
default boolean register(final String diagramType, final Map<String, Class<? extends Action>> actionMap) {
return register(diagramType, actionMap, true);
}

/**
* Registers a set of actions for a diagramType.
*
* @param diagramType The diagramType for which the action is registered.
* @param actionMap A map of actionKind and actions to be registered.
* @param isServerAction This flag indicates if the given actions are handled by the server.
* @return A boolean flag that indicates if the registration was successful.
*/
boolean register(String diagramType, Map<String, Class<? extends Action>> actionMap,
boolean isServerAction);
boolean register(String diagramType, Map<String, Class<? extends Action>> actionMap);

/**
* Returns a list of actions that are handled by the server for the given diagramType.
* Returns a list of actions kinds that are handled by the server for the given diagramType.
*
* @return A list of actions that are handled on the server for the given diagramType.
*/
List<String> getServerHandledAction(String diagramType);
List<String> getHandledActionKinds(String diagramType);

/**
* Returns a map of all registered diagramTypes and their server-handled actions.
* Returns a map of all registered diagramTypes and their server-handled actions kinds.
*
* @return A map of all registered diagramTypes and their server-handled actions.
*/
Map<String, List<String>> getServerHandledActions();
Map<String, List<String>> getHandledActionKinds();

/**
* Returns a map of all currently registered actionKinds and their corresponding {@link Action} class.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/********************************************************************************
* Copyright (c) 2020-2023 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
package org.eclipse.glsp.server.actions;

import static org.eclipse.glsp.server.di.ClientSessionModule.CLIENT_ACTIONS;

import java.util.Set;

import org.eclipse.glsp.server.di.ClientId;
import org.eclipse.glsp.server.di.DiagramType;
import org.eclipse.glsp.server.model.GModelState;
import org.eclipse.glsp.server.protocol.GLSPClient;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.name.Named;

/**
* Component responsible for forwarding actions that are (also) handled by the
* client.
*/
@Singleton
public class ClientActionForwarder {

@Inject
protected Provider<GLSPClient> client;

@Inject
protected GModelState modelState;

@Inject
@ClientId
protected String clientId;

@Inject
@DiagramType
protected String diagramType;

@Inject
@Named(CLIENT_ACTIONS)
protected Set<String> clientActionKinds;

/**
* Processes the given action and checks wether it is a
* `clientAction` i.e. andaction that should be forwared to
* the client to be handled there. If the check is successful
* the action is wrapped in an {@link ActionMessage} and sent to the client.
*
* @param action The action to check and forward
* @return `true` if the action was forwared to the client, `false` otherwise
*/
public boolean handle(final Action action) {
if (shouldForwardToClient(action)) {
ActionMessage message = new ActionMessage(clientId, action);
client.get().process(message);
return true;
}
return false;
}

protected boolean shouldForwardToClient(final Action action) {
if (action.isReceivedFromClient()) {
return false;
}
return (clientActionKinds.contains(action.getKind()) || action instanceof ResponseAction);
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2021 EclipseSource and others.
* Copyright (c) 2021-2023 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -15,22 +15,33 @@
********************************************************************************/
package org.eclipse.glsp.server.di;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;

/**
* Helper module that is typically combined a{@link DiagramModule} to make the
* client session id available in the injector.
* client session specific configuration available in the injector.
*/
public class ClientIdModule extends AbstractModule {
public class ClientSessionModule extends AbstractModule {
public static final String CLIENT_ACTIONS = "ClientActions";

protected final String clientId;
protected final Set<String> clientActionKinds;

public ClientIdModule(final String clientId) {
public ClientSessionModule(final String clientId, final Collection<String> clientActionKinds) {
this.clientId = clientId;
this.clientActionKinds = new HashSet<>(clientActionKinds);
}

@Override
protected void configure() {
bind(String.class).annotatedWith(ClientId.class).toInstance(clientId);
bind(new TypeLiteral<Set<String>>() {}).annotatedWith(Names.named(CLIENT_ACTIONS)).toInstance(clientActionKinds);
}

}
Loading

0 comments on commit 525dd82

Please sign in to comment.