From c96935795bedc798dfc83c82ca46dc5a50860475 Mon Sep 17 00:00:00 2001 From: Tobias Ortmayr Date: Tue, 26 Oct 2021 19:17:36 +0200 Subject: [PATCH] #425#120 Rework Actionhandler/Operationhandler API (#135) * #425#120 Rework Actionhandler/Operationhandler API With the DI rework #127 its no longer necessary to pass the model state object as part of the execute method. instead action/operation handlers can simply directly inject the model state if the want to use it. Since action & operation handlers are now client session scoped an arbitary state object can be injected and used for execution. (Part of eclipse-glsp/glsp/issues/120) - Remove the modelstate argument from the execute() method of `ActionHandler` and `OperationHandler` - Remove `Handler` super interface because it doesn't provide any additional value - Add documentation for affected API. - Introduce new `DefaultActionHandler` & `DefaultOperationHandler` that serve as replacement for the now deprecated `BasicActionHandler` & `BasicOperationHandler` - Deprecate `BasicOperationHandler` & `BasicActionHandler` & `BasicCreateOperationHandler` - Replace usage of `BasicActionHandler` with `DefaultActionHandler` - Replace usage of `BasicOperationHandler' with `DefaultActionHandler` - Replace usage of `BasicCreateOperationhandler' with `DefaultOperationHandler` & `DefaultCreateOperationHandler` Fixes eclipse-glsp/glsp/issues/425 * Remove GModelState from interfaces as it should now be injected instead This simplifies the use of custom model state classes because implementations can now inject their concrete custom class instead of the generic GModelState that they'd have to cast again. Also several implementations often don't need the model state making the method parameter superfluous. Fixes eclipse-glsp/glsp/issues/120 Co-authored-by: Philip Langer --- .../workflow/WorkflowPopupFactory.java | 6 +- .../handler/CreateActivityNodeHandler.java | 3 +- .../handler/CreateCategoryHandler.java | 3 +- .../handler/CreateDecisionNodeHandler.java | 4 +- .../workflow/handler/CreateTaskHandler.java | 3 +- .../CreateWorkflowNodeOperationHandler.java | 5 +- .../workflow/handler/LogActionHandler.java | 9 +-- .../WorkflowRequestContextActionsHandler.java | 7 +- .../labeledit/WorkflowLabelEditValidator.java | 9 ++- .../workflow/layout/WorkflowLayoutEngine.java | 10 ++- .../marker/WorkflowModelValidator.java | 12 ++- ...extOrPreviousNavigationTargetProvider.java | 8 +- ...DocumentationNavigationTargetProvider.java | 7 +- .../WorkflowCommandPaletteActionProvider.java | 6 +- .../WorkflowContextMenuItemProvider.java | 9 ++- .../ApplyTaskEditOperationHandler.java | 15 ++-- .../taskedit/EditTaskOperationHandler.java | 11 ++- .../TaskEditContextActionProvider.java | 8 +- .../workflow/taskedit/TaskEditValidator.java | 9 ++- .../eclipse/glsp/layout/ElkLayoutEngine.java | 8 +- .../server/actions/AbstractActionHandler.java | 78 +++++++++++++++++++ .../glsp/server/actions/ActionHandler.java | 67 ++++++++++++++-- .../server/actions/BasicActionHandler.java | 39 ++++------ .../server/actions/ClientActionHandler.java | 5 +- .../actions/SaveModelActionHandler.java | 25 +++--- .../actions/SetEditModeActionHandler.java | 11 ++- .../eclipse/glsp/server/di/DiagramModule.java | 7 +- .../eclipse/glsp/server/di/ServerModule.java | 2 +- .../RequestTypeHintsActionHandler.java | 7 +- .../RequestClipboardDataActionHandler.java | 9 ++- .../ContextActionsProvider.java | 5 +- .../RequestContextActionsHandler.java | 11 ++- .../contextmenu/ContextMenuItemProvider.java | 14 ++-- .../model/ComputedBoundsActionHandler.java | 13 ++-- .../core/model/JsonFileGModelLoader.java | 6 +- .../core/model/ModelSourceLoader.java | 6 +- .../core/model/ModelSubmissionHandler.java | 31 ++++---- .../core/model/RequestModelActionHandler.java | 23 +++--- .../ApplyLabelEditOperationHandler.java | 11 ++- .../directediting/ContextEditValidator.java | 7 +- .../directediting/LabelEditValidator.java | 3 +- .../RequestEditValidationHandler.java | 11 ++- .../modelsourcewatcher/FileWatcher.java | 26 +++++-- .../ModelSourceWatcher.java | 22 ++---- .../navigation/NavigationTargetProvider.java | 6 +- ...RequestNavigationTargetsActionHandler.java | 12 ++- .../ResolveNavigationTargetActionHandler.java | 11 ++- .../features/popup/PopupModelFactory.java | 6 +- .../popup/RequestPopupModelActionHandler.java | 13 ++-- .../toolpalette/ToolPaletteItemProvider.java | 10 +-- .../undoredo/UndoRedoActionHandler.java | 9 ++- .../features/validation/ModelValidator.java | 5 +- .../validation/RequestMarkersHandler.java | 13 ++-- .../actions/DefaultActionDispatcher.java | 6 +- .../DefaultContextEditValidatorRegistry.java | 6 +- .../labeledit/ValidateLabelEditAdapter.java | 10 ++- .../DefaultToolPaletteItemProvider.java | 3 +- .../glsp/server/layout/LayoutEngine.java | 8 +- .../AbstractCreateOperationHandler.java | 59 ++++++++++++++ .../operations/AbstractOperationHandler.java | 57 ++++++++++++++ .../BasicCreateOperationHandler.java | 30 ++++--- .../operations/BasicOperationHandler.java | 32 ++++---- .../glsp/server/operations/Operation.java | 2 + .../operations/OperationActionHandler.java | 19 +++-- .../server/operations/OperationHandler.java | 42 ++++++++-- .../gmodel/ChangeBoundsOperationHandler.java | 16 ++-- .../gmodel/ChangeRoutingPointsHandler.java | 11 ++- .../gmodel/CompoundOperationHandler.java | 15 ++-- .../gmodel/CreateEdgeOperationHandler.java | 25 +++--- .../gmodel/CreateNodeOperationHandler.java | 22 +++--- .../gmodel/CutOperationHandler.java | 14 ++-- .../gmodel/DeleteOperationHandler.java | 19 +++-- .../gmodel/LayoutOperationHandler.java | 10 +-- .../gmodel/PasteOperationHandler.java | 9 ++- .../gmodel/ReconnectEdgeOperationHandler.java | 12 ++- .../eclipse/glsp/server/types/Handler.java | 24 ------ .../modelsourcewatcher/FileWatcherTest.java | 30 +++---- 77 files changed, 744 insertions(+), 413 deletions(-) create mode 100644 plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/AbstractActionHandler.java create mode 100644 plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractCreateOperationHandler.java create mode 100644 plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractOperationHandler.java delete mode 100644 plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/types/Handler.java diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowPopupFactory.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowPopupFactory.java index 4b78841a..8628fcb6 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowPopupFactory.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowPopupFactory.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -28,7 +28,6 @@ import org.eclipse.glsp.graph.GraphFactory; import org.eclipse.glsp.server.features.popup.PopupModelFactory; import org.eclipse.glsp.server.features.popup.RequestPopupModelAction; -import org.eclipse.glsp.server.model.GModelState; public class WorkflowPopupFactory implements PopupModelFactory { @@ -44,8 +43,7 @@ private String generateBody(final TaskNode task) { private static final String NL = "
"; @Override - public Optional createPopupModel(final GModelElement element, final RequestPopupModelAction action, - final GModelState modelState) { + public Optional createPopupModel(final GModelElement element, final RequestPopupModelAction action) { if (element != null && element instanceof TaskNode) { TaskNode task = (TaskNode) element; GHtmlRoot root = GraphFactory.eINSTANCE.createGHtmlRoot(); diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateActivityNodeHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateActivityNodeHandler.java index d29586d5..10a8915f 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateActivityNodeHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateActivityNodeHandler.java @@ -44,8 +44,7 @@ protected ActivityNodeBuilder builder(final Optional point, final GModel } @Override - protected GNode createNode(final Optional point, final Map args, - final GModelState modelState) { + protected GNode createNode(final Optional point, final Map args) { return builder(point, modelState).build(); } diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateCategoryHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateCategoryHandler.java index f363d18b..479dfbae 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateCategoryHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateCategoryHandler.java @@ -42,8 +42,7 @@ protected CategoryNodeBuilder builder(final Optional point, final GModel } @Override - protected GNode createNode(final Optional point, final Map args, - final GModelState modelState) { + protected GNode createNode(final Optional point, final Map args) { return builder(point, modelState).build(); } diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateDecisionNodeHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateDecisionNodeHandler.java index ee43c981..da4a9b38 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateDecisionNodeHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateDecisionNodeHandler.java @@ -23,7 +23,6 @@ import org.eclipse.glsp.graph.GNode; import org.eclipse.glsp.graph.GPoint; import org.eclipse.glsp.graph.builder.impl.GLayoutOptions; -import org.eclipse.glsp.server.model.GModelState; public class CreateDecisionNodeHandler extends CreateActivityNodeHandler { @@ -32,8 +31,7 @@ public CreateDecisionNodeHandler() { } @Override - protected GNode createNode(final Optional point, final Map args, - final GModelState modelState) { + protected GNode createNode(final Optional point, final Map args) { String nodeType = ModelTypes.toNodeType(getElementTypeId()); return new ActivityNodeBuilder(getElementTypeId(), nodeType) // .layoutOptions(new GLayoutOptions().minHeight(32d).minWidth(32d)) // diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateTaskHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateTaskHandler.java index a98c2aa9..e12b8c13 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateTaskHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateTaskHandler.java @@ -52,8 +52,7 @@ protected TaskNodeBuilder builder(final Optional point, final GModelStat } @Override - protected GNode createNode(final Optional point, final Map args, - final GModelState modelState) { + protected GNode createNode(final Optional point, final Map args) { return builder(point, modelState).build(); } diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateWorkflowNodeOperationHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateWorkflowNodeOperationHandler.java index 5d7d392b..439fe220 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateWorkflowNodeOperationHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/CreateWorkflowNodeOperationHandler.java @@ -22,7 +22,6 @@ import org.eclipse.glsp.graph.GCompartment; import org.eclipse.glsp.graph.GModelElement; import org.eclipse.glsp.graph.GPoint; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.operations.CreateNodeOperation; import org.eclipse.glsp.server.operations.gmodel.CreateNodeOperationHandler; @@ -38,8 +37,8 @@ protected Optional getLocation(final CreateNodeOperation operation) { } @Override - protected Optional getContainer(final CreateNodeOperation operation, final GModelState modelState) { - Optional container = super.getContainer(operation, modelState); + protected Optional getContainer(final CreateNodeOperation operation) { + Optional container = super.getContainer(operation); // If the container is a Category node, find its structure compartment Optional structCompt = container.filter(Category.class::isInstance).map(Category.class::cast) .flatMap(this::getCategoryCompartment); diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/LogActionHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/LogActionHandler.java index b8b14c57..8026213c 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/LogActionHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/LogActionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -22,15 +22,14 @@ import org.apache.log4j.Logger; import org.eclipse.glsp.example.workflow.action.LogAction; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; -import org.eclipse.glsp.server.model.GModelState; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.types.Severity; -public class LogActionHandler extends BasicActionHandler { +public class LogActionHandler extends AbstractActionHandler { private static Logger LOG = Logger.getLogger(LogActionHandler.class); @Override - protected List executeAction(final LogAction action, final GModelState modelState) { + protected List executeAction(final LogAction action) { LOG.log(toLevel(action.getSeverity()), action.getMessage()); return Collections.emptyList(); } diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/WorkflowRequestContextActionsHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/WorkflowRequestContextActionsHandler.java index 5e3a5986..1b045fb8 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/WorkflowRequestContextActionsHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/handler/WorkflowRequestContextActionsHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -23,13 +23,12 @@ import org.eclipse.glsp.server.features.contextactions.RequestContextActions; import org.eclipse.glsp.server.features.contextactions.RequestContextActionsHandler; import org.eclipse.glsp.server.features.contextactions.SetContextActions; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.types.Severity; public class WorkflowRequestContextActionsHandler extends RequestContextActionsHandler { @Override - public List executeAction(final RequestContextActions action, final GModelState modelState) { - List actions = new ArrayList<>(super.executeAction(action, modelState)); + public List executeAction(final RequestContextActions action) { + List actions = new ArrayList<>(super.executeAction(action)); actions.stream() .filter(SetContextActions.class::isInstance) .map(SetContextActions.class::cast) diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/labeledit/WorkflowLabelEditValidator.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/labeledit/WorkflowLabelEditValidator.java index 09a1b000..51507555 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/labeledit/WorkflowLabelEditValidator.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/labeledit/WorkflowLabelEditValidator.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019-2020 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -23,10 +23,15 @@ import org.eclipse.glsp.server.features.directediting.ValidationStatus; import org.eclipse.glsp.server.model.GModelState; +import com.google.inject.Inject; + public class WorkflowLabelEditValidator implements LabelEditValidator { + @Inject + protected GModelState modelState; + @Override - public ValidationStatus validate(final GModelState modelState, final String label, final GModelElement element) { + public ValidationStatus validate(final String label, final GModelElement element) { if (label.length() < 1) { return ValidationStatus.error("Name must not be empty"); } diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/layout/WorkflowLayoutEngine.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/layout/WorkflowLayoutEngine.java index 992bb749..d26e9441 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/layout/WorkflowLayoutEngine.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/layout/WorkflowLayoutEngine.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -20,9 +20,15 @@ import org.eclipse.glsp.layout.GLSPLayoutConfigurator; import org.eclipse.glsp.server.model.GModelState; +import com.google.inject.Inject; + public class WorkflowLayoutEngine extends ElkLayoutEngine { + + @Inject + protected GModelState modelState; + @Override - public void layout(final GModelState modelState) { + public void layout() { if (modelState.getRoot() instanceof GGraph) { GLSPLayoutConfigurator configurator = new GLSPLayoutConfigurator(); configurator.configureByType("graph"); diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/marker/WorkflowModelValidator.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/marker/WorkflowModelValidator.java index 02391de2..3fc649f2 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/marker/WorkflowModelValidator.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/marker/WorkflowModelValidator.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -33,10 +33,15 @@ import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.utils.GModelUtil; +import com.google.inject.Inject; + public class WorkflowModelValidator implements ModelValidator { + @Inject + protected GModelState modelState; + @Override - public List validate(final GModelState modelState, final GModelElement... elements) { + public List validate(final GModelElement... elements) { List markers = new ArrayList<>(); for (GModelElement element : elements) { @@ -51,8 +56,7 @@ public List validate(final GModelState modelState, final GModelElement.. } } if (element.getChildren() != null) { - markers.addAll(validate(modelState, - element.getChildren().toArray(new GModelElement[element.getChildren().size()]))); + markers.addAll(validate(element.getChildren().toArray(new GModelElement[element.getChildren().size()]))); } } return markers; diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/AbstractNextOrPreviousNavigationTargetProvider.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/AbstractNextOrPreviousNavigationTargetProvider.java index 1a3f66f4..40bc529c 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/AbstractNextOrPreviousNavigationTargetProvider.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/AbstractNextOrPreviousNavigationTargetProvider.java @@ -31,11 +31,15 @@ import org.eclipse.glsp.server.utils.ClientOptionsUtil; import org.eclipse.glsp.server.utils.MapUtil; +import com.google.inject.Inject; + public abstract class AbstractNextOrPreviousNavigationTargetProvider implements NavigationTargetProvider { + @Inject + protected GModelState modelState; + @Override - public List getTargets(final EditorContext editorContext, - final GModelState modelState) { + public List getTargets(final EditorContext editorContext) { Optional sourceUri = MapUtil.getValue(modelState.getClientOptions(), ClientOptionsUtil.SOURCE_URI); return editorContext.getSelectedElementIds().stream() .flatMap(id -> modelState.getIndex().get(id).stream()) diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/NodeDocumentationNavigationTargetProvider.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/NodeDocumentationNavigationTargetProvider.java index 476da820..e5f6bba6 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/NodeDocumentationNavigationTargetProvider.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/NodeDocumentationNavigationTargetProvider.java @@ -30,6 +30,8 @@ import org.eclipse.glsp.server.utils.ClientOptionsUtil; import org.eclipse.glsp.server.utils.MapUtil; +import com.google.inject.Inject; + /** * An example {@link NavigationTargetProvider} that opens an md file and selects a specified range. *

@@ -41,8 +43,11 @@ public class NodeDocumentationNavigationTargetProvider implements NavigationTarg @Override public String getTargetTypeId() { return "documentation"; } + @Inject + protected GModelState modelState; + @Override - public List getTargets(final EditorContext editorContext, final GModelState modelState) { + public List getTargets(final EditorContext editorContext) { if (editorContext.getSelectedElementIds().size() == 1) { Optional taskNode = modelState.getIndex() .findElementByClass(editorContext.getSelectedElementIds().get(0), TaskNode.class); diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowCommandPaletteActionProvider.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowCommandPaletteActionProvider.java index 64926706..0d93aff3 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowCommandPaletteActionProvider.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowCommandPaletteActionProvider.java @@ -40,12 +40,16 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.google.inject.Inject; public class WorkflowCommandPaletteActionProvider implements CommandPaletteActionProvider { + @Inject + protected GModelState modelState; + @Override @SuppressWarnings("checkstyle:CyclomaticComplexity") - public List getActions(final EditorContext editorContext, final GModelState modelState) { + public List getActions(final EditorContext editorContext) { List actions = Lists.newArrayList(); if (modelState.isReadonly()) { return actions; diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowContextMenuItemProvider.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowContextMenuItemProvider.java index 19d2b81d..34b8ee33 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowContextMenuItemProvider.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/provider/WorkflowContextMenuItemProvider.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -31,13 +31,16 @@ import org.eclipse.glsp.server.operations.CreateNodeOperation; import com.google.common.collect.Lists; +import com.google.inject.Inject; public class WorkflowContextMenuItemProvider implements ContextMenuItemProvider { + @Inject + protected GModelState modelState; + @Override public List getItems(final List selectedElementIds, final GPoint position, - final Map args, - final GModelState modelState) { + final Map args) { if (modelState.isReadonly()) { return Collections.emptyList(); } diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/ApplyTaskEditOperationHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/ApplyTaskEditOperationHandler.java index cbbd1f82..0486cc6c 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/ApplyTaskEditOperationHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/ApplyTaskEditOperationHandler.java @@ -17,25 +17,28 @@ import org.eclipse.glsp.server.actions.ActionDispatcher; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.types.GLSPServerException; import com.google.inject.Inject; -public class ApplyTaskEditOperationHandler extends BasicOperationHandler { +public class ApplyTaskEditOperationHandler extends AbstractOperationHandler { @Inject - private ActionDispatcher actionProcessor; + protected ActionDispatcher actionDispatcher; + + @Inject + protected GModelState modelState; @Override - protected void executeOperation(final ApplyTaskEditOperation operation, final GModelState modelState) { + protected void executeOperation(final ApplyTaskEditOperation operation) { String text = operation.getExpression(); if (text.startsWith(TaskEditContextActionProvider.DURATION_PREFIX)) { String durationString = text.substring(TaskEditContextActionProvider.DURATION_PREFIX.length()); - actionProcessor.dispatch(new EditTaskOperation(operation.getTaskId(), "duration", durationString)); + actionDispatcher.dispatch(new EditTaskOperation(operation.getTaskId(), "duration", durationString)); } else if (text.startsWith(TaskEditContextActionProvider.TYPE_PREFIX)) { String typeString = text.substring(TaskEditContextActionProvider.TYPE_PREFIX.length()); - actionProcessor.dispatch(new EditTaskOperation(operation.getTaskId(), "taskType", typeString)); + actionDispatcher.dispatch(new EditTaskOperation(operation.getTaskId(), "taskType", typeString)); } else { throw new GLSPServerException( "Cannot process 'ApplyTaskEditOperation' expression: " + operation.getExpression()); diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/EditTaskOperationHandler.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/EditTaskOperationHandler.java index 7139a688..67f4d4be 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/EditTaskOperationHandler.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/EditTaskOperationHandler.java @@ -19,13 +19,18 @@ import org.eclipse.glsp.example.workflow.wfgraph.TaskNode; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.types.GLSPServerException; -public class EditTaskOperationHandler extends BasicOperationHandler { +import com.google.inject.Inject; + +public class EditTaskOperationHandler extends AbstractOperationHandler { + + @Inject + protected GModelState modelState; @Override - protected void executeOperation(final EditTaskOperation operation, final GModelState modelState) { + protected void executeOperation(final EditTaskOperation operation) { Optional task = modelState.getIndex().findElementByClass(operation.getTaskId(), TaskNode.class); if (task.isEmpty()) { throw new RuntimeException("Cannot find task with id '" + operation.getTaskId() + "'"); diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditContextActionProvider.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditContextActionProvider.java index f4fe4e4e..c3643464 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditContextActionProvider.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditContextActionProvider.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -27,6 +27,7 @@ import org.eclipse.glsp.server.types.EditorContext; import com.google.common.collect.Lists; +import com.google.inject.Inject; public class TaskEditContextActionProvider implements ContextActionsProvider { @@ -37,8 +38,11 @@ public class TaskEditContextActionProvider implements ContextActionsProvider { @Override public String getContextId() { return "task-editor"; } + @Inject + protected GModelState modelState; + @Override - public List getActions(final EditorContext editorContext, final GModelState modelState) { + public List getActions(final EditorContext editorContext) { String text = editorContext.getArgs().getOrDefault("text", ""); Optional taskNode = modelState.getIndex() .findElementByClass(editorContext.getSelectedElementIds().get(0), TaskNode.class); diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditValidator.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditValidator.java index 46e2e419..f38d98fd 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditValidator.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/taskedit/TaskEditValidator.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -20,14 +20,19 @@ import org.eclipse.glsp.server.features.directediting.ValidationStatus; import org.eclipse.glsp.server.model.GModelState; +import com.google.inject.Inject; + public class TaskEditValidator implements ContextEditValidator { @Override public String getContextId() { return "task-editor"; } + @Inject + protected GModelState modelState; + @SuppressWarnings("checkstyle:cyclomaticComplexity") @Override - public ValidationStatus validate(final RequestEditValidationAction action, final GModelState modelState) { + public ValidationStatus validate(final RequestEditValidationAction action) { String text = action.getText(); if (text.startsWith(TaskEditContextActionProvider.DURATION_PREFIX)) { String durationString = text.substring(TaskEditContextActionProvider.DURATION_PREFIX.length()); diff --git a/plugins/org.eclipse.glsp.layout/src/org/eclipse/glsp/layout/ElkLayoutEngine.java b/plugins/org.eclipse.glsp.layout/src/org/eclipse/glsp/layout/ElkLayoutEngine.java index 93e33e08..01be8ab9 100644 --- a/plugins/org.eclipse.glsp.layout/src/org/eclipse/glsp/layout/ElkLayoutEngine.java +++ b/plugins/org.eclipse.glsp.layout/src/org/eclipse/glsp/layout/ElkLayoutEngine.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2018 TypeFox and others. + * Copyright (c) 2018-2021 TypeFox and others. * (c) 2019-2021 EclipseSource (adaptation for GModel) * * This program and the accompanying materials are made available under the @@ -63,6 +63,7 @@ import org.eclipse.glsp.server.model.GModelState; import com.google.common.collect.Maps; +import com.google.inject.Inject; /** * Layout engine that uses the Eclipse @@ -83,6 +84,9 @@ public static void initialize(final ILayoutMetaDataProvider... providers) { LayoutMetaDataService.getInstance().registerLayoutMetaDataProviders(providers); } + @Inject + protected GModelState modelState; + private IGraphLayoutEngine engine = new RecursiveGraphLayoutEngine(); protected final ElkGraphFactory factory = ElkGraphFactory.eINSTANCE; @@ -95,7 +99,7 @@ public static void initialize(final ILayoutMetaDataProvider... providers) { * for your model using a {@link SprottyLayoutConfigurator}. */ @Override - public void layout(final GModelState modelState) { + public void layout() { if (modelState.getRoot() instanceof GGraph) { layout((GGraph) modelState.getRoot(), null); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/AbstractActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/AbstractActionHandler.java new file mode 100644 index 00000000..2675ab72 --- /dev/null +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/AbstractActionHandler.java @@ -0,0 +1,78 @@ +/******************************************************************************** + * Copyright (c) 2019-2021 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 java.util.Arrays; +import java.util.List; + +import org.eclipse.glsp.server.internal.util.GenericsUtil; + +/** + * Basic {@link ActionHandler} implementation that can handle exactly one {@link Action} type/class. + * It handles the overhead of casting the action object received via the {@link ActionHandler#execute(Action)} method + * to the correct handled subtype. Subclasses only have to implement the + * {@link AbstractActionHandler#executeAction(Action)} method + * and can work directly with the correct subtype instead of having to manually cast it. + * + * @param class of the handled action type + */ +public abstract class AbstractActionHandler implements ActionHandler { + protected final Class actionType; + + public AbstractActionHandler() { + this.actionType = deriveActionType(); + } + + @SuppressWarnings("unchecked") + protected Class deriveActionType() { + return (Class) GenericsUtil.getGenericTypeParameterClass(getClass(), AbstractActionHandler.class); + } + + @Override + public boolean handles(final Action action) { + return actionType.isInstance(action); + } + + @Override + public List execute(final Action action) { + if (handles(action)) { + A actualAction = actionType.cast(action); + return executeAction(actualAction); + } + return none(); + } + + /** + * Executes the action handler for the given {@link Action} and returns a list of response actions that should be + * dispatched by the {@link ActionDispatcher}. If the given action cannot be handled by this action handler an empty + * list is returned. + * + * @param actualAction The action that should be processed. + * @return A list of response actions that should be dispatched. + */ + protected abstract List executeAction(A actualAction); + + /** + * Returns the {@link Class} of the {@link Action} subtype that can be handled by this action handler. + * + * @return the handled action subclass. + */ + public Class getActionType() { return actionType; } + + @Override + public List> getHandledActionTypes() { return Arrays.asList(actionType); } + +} diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ActionHandler.java index 1875f22e..dcf9b2b8 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ActionHandler.java @@ -21,30 +21,83 @@ import java.util.List; import java.util.Optional; -import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.types.Handler; - -public interface ActionHandler extends Handler { +/** + * An action handler can execute certain {@link Action} types (subclasses) that are dispatched by the + * {@link ActionDispatcher}. The action handler processes the action in the {@link ActionHandler#execute(Action)} + * method and returns a list of response actions to be dispatched as a result of processing the original action. + * One action handler can handle multiple different action types, see {@link ActionHandler#getHandledActionTypes()}. + */ +public interface ActionHandler { + /** + * Returns the list of action type (subclasses) that can be handled by this action handler. + * + * @return A list of {@link Action} classes that can be handled. + */ List> getHandledActionTypes(); - @Override + /** + * Validates whether the given {@link Action} can be handled by this action handler. + * The default implementation uses the list of handled action types ({@link ActionHandler#getHandledActionTypes()} + * to determine whether this handler can handle an action. Only actions that are instances of one of these types can + * be handled. + * + * @param action The action that should be validated. + * @return `true` if the given action can be handled, `false` otherwise. + */ default boolean handles(final Action action) { return getHandledActionTypes().stream().anyMatch(clazz -> clazz.isInstance(action)); } + /** + * Executes the action handler for the given {@link Action} and returns a list of response actions that should be + * dispatched as a result of processing the original action. This list can be empty, if no more actions need to be executed. + * list is returned. + * + * @param action The action that should be processed. + * @return A list of response actions that should be dispatched. + */ + List execute(Action action); + + /** + * Helper method to convert the given {@link Action} to a {@link List}. + * + * @param action One ore more action objects that should be converted. + * @return The given action objects as list. + */ default List listOf(final Action... action) { return Arrays.asList(action); } + /** + * Helper method to convert the given {@link Optional} action to a {@link List}. + * + * @param optionalAction The optional action that should be converted. + * @return A list of the given action or an empty list if no value was present. + */ default List listOf(final Optional optionalAction) { List actions = new ArrayList<>(); optionalAction.ifPresent(action -> actions.add(action)); return actions; } - List execute(Action action, GModelState modelState); - + /** + * Helper method that can be used to return an empty {@link List} of {@link Action}s. + * + * @return An empty action list. + */ default List none() { return Collections.emptyList(); } + + /** + * Returns the priority of this action handler. The priority is used to derive the execution order if multiple + * action handlers should execute the same {@link Action}. The default priority is `0` and the priority is sorted + * descending. This means handlers with a priority >0 are executed before handlers with a default priority and + * handlers with a + * priority <0 are executed afterwards. + * + * @return the priority as integer. + */ + default int getPriority() { return 0; } + } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/BasicActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/BasicActionHandler.java index a3c8bcdc..6e6c2081 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/BasicActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/BasicActionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -15,45 +15,34 @@ ********************************************************************************/ package org.eclipse.glsp.server.actions; -import java.util.Arrays; import java.util.List; import org.eclipse.glsp.server.internal.util.GenericsUtil; import org.eclipse.glsp.server.model.GModelState; -public abstract class BasicActionHandler implements ActionHandler { - protected final Class actionType; +import com.google.inject.Inject; - public BasicActionHandler() { - this.actionType = deriveActionType(); - } +/** + * Deprecated, will be removed with version 1.0. + * Please use {@link AbstractActionHandler} instead and directly inject the {@link GModelState}. + */ +@Deprecated +public abstract class BasicActionHandler extends AbstractActionHandler { + + @Inject + protected GModelState modelState; + @Override @SuppressWarnings("unchecked") protected Class deriveActionType() { return (Class) GenericsUtil.getGenericTypeParameterClass(getClass(), BasicActionHandler.class); } @Override - public boolean handles(final Action action) { - return actionType.isInstance(action); - } - - @Override - public List execute(final Action action, final GModelState modelState) { - if (handles(action)) { - T actualAction = actionType.cast(action); - return executeAction(actualAction, modelState); - } - return none(); + public List executeAction(final T actualAction) { + return executeAction(actualAction, modelState); } protected abstract List executeAction(T actualAction, GModelState modelState); - public Class getActionType() { return actionType; } - - @Override - public List> getHandledActionTypes() { - return Arrays.asList(actionType); - } - } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ClientActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ClientActionHandler.java index 215c0e5d..ef6793e4 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ClientActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/ClientActionHandler.java @@ -34,6 +34,9 @@ public class ClientActionHandler implements ActionHandler { @Inject protected Provider client; + @Inject + protected GModelState modelState; + private final List> handledActionTypes; @Inject @@ -45,7 +48,7 @@ public ClientActionHandler(@Named(CLIENT_ACTIONS) final Set clientAction public List> getHandledActionTypes() { return handledActionTypes; } @Override - public List execute(final Action action, final GModelState modelState) { + public List execute(final Action action) { send(modelState.getClientId(), action); return Collections.emptyList(); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SaveModelActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SaveModelActionHandler.java index 7f7c95c3..a33fd95e 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SaveModelActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SaveModelActionHandler.java @@ -37,32 +37,35 @@ import com.google.gson.Gson; import com.google.inject.Inject; -public class SaveModelActionHandler extends BasicActionHandler { +public class SaveModelActionHandler extends AbstractActionHandler { private static final Logger LOG = Logger.getLogger(SaveModelActionHandler.class); @Inject protected GraphGsonConfigurationFactory gsonConfigurator; @Inject - private Optional modelSourceWatcher; + protected Optional modelSourceWatcher; + + @Inject + protected GModelState modelState; @Override - public List executeAction(final SaveModelAction action, final GModelState modelState) { - modelSourceWatcher.ifPresent(watcher -> watcher.pauseWatching(modelState)); + public List executeAction(final SaveModelAction action) { + modelSourceWatcher.ifPresent(watcher -> watcher.pauseWatching()); try { - saveModelState(action, modelState); + saveModelState(action); } finally { - modelSourceWatcher.ifPresent(watcher -> watcher.continueWatching(modelState)); + modelSourceWatcher.ifPresent(watcher -> watcher.continueWatching()); } return listOf(new SetDirtyStateAction(modelState.isDirty(), SetDirtyStateAction.Reason.SAVE)); } - protected void saveModelState(final SaveModelAction action, final GModelState modelState) { - File file = convertToFile(action, modelState); + protected void saveModelState(final SaveModelAction action) { + File file = convertToFile(action); try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) { Gson gson = gsonConfigurator.configureGson().setPrettyPrinting().create(); gson.toJson(modelState.getRoot(), GGraph.class, writer); - if (saveIsDone(action, modelState)) { + if (saveIsDone(action)) { modelState.saveIsDone(); } } catch (IOException e) { @@ -71,12 +74,12 @@ protected void saveModelState(final SaveModelAction action, final GModelState mo } } - protected boolean saveIsDone(final SaveModelAction action, final GModelState modelState) { + protected boolean saveIsDone(final SaveModelAction action) { String sourceUri = ClientOptionsUtil.adaptUri(modelState.getClientOptions().get(ClientOptionsUtil.SOURCE_URI)); return action.getFileUri().map(uri -> ClientOptionsUtil.adaptUri(uri).equals(sourceUri)).orElse(true); } - protected File convertToFile(final SaveModelAction action, final GModelState modelState) { + protected File convertToFile(final SaveModelAction action) { if (action.getFileUri().isPresent()) { return ClientOptionsUtil.getAsFile(action.getFileUri().get()); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SetEditModeActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SetEditModeActionHandler.java index 3c71bfca..6fae02c7 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SetEditModeActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actions/SetEditModeActionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -19,10 +19,15 @@ import org.eclipse.glsp.server.model.GModelState; -public class SetEditModeActionHandler extends BasicActionHandler { +import com.google.inject.Inject; + +public class SetEditModeActionHandler extends AbstractActionHandler { + + @Inject + protected GModelState modelState; @Override - protected List executeAction(final SetEditModeAction action, final GModelState modelState) { + protected List executeAction(final SetEditModeAction action) { modelState.setEditMode(action.getEditMode()); return none(); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/DiagramModule.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/DiagramModule.java index 76a50073..9fca3257 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/DiagramModule.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/DiagramModule.java @@ -166,7 +166,7 @@ protected void configureBase() { bind(DiagramConfiguration.class).to(bindDiagramConfiguration()).in(DiagramGlobalSingleton.class); bind(ServerConfigurationContribution.class).to(bindServerConfigurationContribution()).in(Singleton.class); // Model-related bindings - bind(GModelState.class).to(bindGModelState()).in(Singleton.class); + configureGModelState(bindGModelState()); bind(ModelSourceLoader.class).to(bindSourceModelLoader()); bind(GModelFactory.class).to(bindGModelFactory()); bindOptionally(ModelSourceWatcher.class, bindModelSourceWatcher()) @@ -225,6 +225,11 @@ protected Class bindServerConfigurati return DefaultServerConfigurationContribution.class; } + protected void configureGModelState(final Class gmodelStateClass) { + bind(gmodelStateClass).in(Singleton.class); + bind(GModelState.class).to(gmodelStateClass); + } + protected Class bindGModelState() { return DefaultGModelState.class; } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/ServerModule.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/ServerModule.java index 9c9bdbc1..21904171 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/ServerModule.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/ServerModule.java @@ -86,7 +86,7 @@ public class ServerModule extends GLSPModule { public ServerModule configureDiagramModule(final DiagramModule diagramModule, final Module... mixinModules) { String diagramType = diagramModule.getDiagramType(); Preconditions.checkState(!diagramModules.containsKey(diagramType), - "A module configuration is alreay present for diagram type: " + diagramType); + "A module configuration is already present for diagram type: " + diagramType); Module combinedModule = ModuleUtil.mixin(diagramModule, mixinModules); diagramModules.put(diagramType, combinedModule); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/diagram/RequestTypeHintsActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/diagram/RequestTypeHintsActionHandler.java index 629745c7..263ff53d 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/diagram/RequestTypeHintsActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/diagram/RequestTypeHintsActionHandler.java @@ -18,17 +18,16 @@ import java.util.List; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; -import org.eclipse.glsp.server.model.GModelState; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import com.google.inject.Inject; -public class RequestTypeHintsActionHandler extends BasicActionHandler { +public class RequestTypeHintsActionHandler extends AbstractActionHandler { @Inject protected DiagramConfiguration diagramConfiguration; @Override - public List executeAction(final RequestTypeHintsAction action, final GModelState modelState) { + public List executeAction(final RequestTypeHintsAction action) { return listOf(new SetTypeHintsAction(diagramConfiguration.getShapeTypeHints(), diagramConfiguration.getEdgeTypeHints())); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/clipboard/RequestClipboardDataActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/clipboard/RequestClipboardDataActionHandler.java index 35c65ddf..dd575358 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/clipboard/RequestClipboardDataActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/clipboard/RequestClipboardDataActionHandler.java @@ -22,7 +22,7 @@ import org.eclipse.glsp.graph.GModelElement; import org.eclipse.glsp.graph.GModelIndex; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.gson.GraphGsonConfigurationFactory; import org.eclipse.glsp.server.model.GModelState; @@ -31,10 +31,13 @@ import com.google.gson.JsonArray; import com.google.inject.Inject; -public class RequestClipboardDataActionHandler extends BasicActionHandler { +public class RequestClipboardDataActionHandler extends AbstractActionHandler { protected final Gson gson; + @Inject + protected GModelState modelState; + @Inject public RequestClipboardDataActionHandler(final GraphGsonConfigurationFactory gsonConfigurator) { GsonBuilder builder = gsonConfigurator.configureGson(); @@ -42,7 +45,7 @@ public RequestClipboardDataActionHandler(final GraphGsonConfigurationFactory gso } @Override - public List executeAction(final RequestClipboardDataAction action, final GModelState modelState) { + public List executeAction(final RequestClipboardDataAction action) { JsonArray jsonArray = new JsonArray(); GModelIndex index = modelState.getIndex(); Set selectedElements = index.getAll(action.getEditorContext().getSelectedElementIds()); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/ContextActionsProvider.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/ContextActionsProvider.java index ad1746b0..9827e1f5 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/ContextActionsProvider.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/ContextActionsProvider.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -18,14 +18,13 @@ import java.util.List; import org.eclipse.glsp.server.features.directediting.LabeledAction; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.types.EditorContext; public interface ContextActionsProvider { String getContextId(); - List getActions(EditorContext editorContext, GModelState modelState); + List getActions(EditorContext editorContext); default boolean handles(final String contextId) { return getContextId().equals(contextId); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/RequestContextActionsHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/RequestContextActionsHandler.java index 268bc33e..73761bd3 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/RequestContextActionsHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextactions/RequestContextActionsHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -18,25 +18,24 @@ import java.util.ArrayList; import java.util.List; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; import org.eclipse.glsp.server.features.directediting.LabeledAction; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.types.EditorContext; import com.google.inject.Inject; -public class RequestContextActionsHandler extends BasicActionHandler { +public class RequestContextActionsHandler extends AbstractActionHandler { @Inject protected ContextActionsProviderRegistry contextActionsProviderRegistry; @Override - public List executeAction(final RequestContextActions action, final GModelState modelState) { + public List executeAction(final RequestContextActions action) { EditorContext editorContext = action.getEditorContext(); List actions = new ArrayList<>(); contextActionsProviderRegistry.get(action.getContextId()) - .map(provider -> provider.getActions(editorContext, modelState)) + .map(provider -> provider.getActions(editorContext)) .ifPresent(labeledActions -> actions.addAll(labeledActions)); return listOf(new SetContextActions(actions, action.getEditorContext().getArgs())); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextmenu/ContextMenuItemProvider.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextmenu/ContextMenuItemProvider.java index 43f42899..193fb349 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextmenu/ContextMenuItemProvider.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/contextmenu/ContextMenuItemProvider.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -23,7 +23,6 @@ import org.eclipse.glsp.graph.GPoint; import org.eclipse.glsp.server.features.contextactions.ContextActionsProvider; import org.eclipse.glsp.server.features.directediting.LabeledAction; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.types.EditorContext; @FunctionalInterface @@ -34,14 +33,11 @@ public interface ContextMenuItemProvider extends ContextActionsProvider { @Override default String getContextId() { return ContextMenuItemProvider.KEY; } - List getItems(List selectedElementIds, GPoint position, Map args, - GModelState modelState); + List getItems(List selectedElementIds, GPoint position, Map args); @Override - default List getActions(final EditorContext editorContext, - final GModelState modelState) { - return getItems(editorContext.getSelectedElementIds(), editorContext.getLastMousePosition().orElse(point(0, 0)), - editorContext.getArgs(), - modelState); + default List getActions(final EditorContext editorContext) { + final GPoint position = editorContext.getLastMousePosition().orElse(point(0, 0)); + return getItems(editorContext.getSelectedElementIds(), position, editorContext.getArgs()); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ComputedBoundsActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ComputedBoundsActionHandler.java index a950bb53..f8867d03 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ComputedBoundsActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ComputedBoundsActionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -18,25 +18,28 @@ import java.util.List; import org.eclipse.glsp.graph.GModelRoot; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.utils.LayoutUtil; import com.google.inject.Inject; -public class ComputedBoundsActionHandler extends BasicActionHandler { +public class ComputedBoundsActionHandler extends AbstractActionHandler { @Inject protected ModelSubmissionHandler submissionHandler; + @Inject + protected GModelState modelState; + @Override - public List executeAction(final ComputedBoundsAction action, final GModelState modelState) { + public List executeAction(final ComputedBoundsAction action) { synchronized (submissionHandler.getModelLock()) { GModelRoot model = modelState.getRoot(); if (model != null && model.getRevision() == action.getRevision()) { LayoutUtil.applyBounds(model, action, modelState); - return submissionHandler.submitModelDirectly(modelState); + return submissionHandler.submitModelDirectly(); } } return none(); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileGModelLoader.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileGModelLoader.java index 2543a78e..18425df3 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileGModelLoader.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileGModelLoader.java @@ -45,11 +45,15 @@ public class JsonFileGModelLoader implements ModelSourceLoader { private static Logger LOG = Logger.getLogger(JsonFileGModelLoader.class); private static String EMPTY_ROOT_ID = "glsp-graph"; + @Inject private GraphGsonConfigurationFactory gsonConfiguratior; + @Inject + protected GModelState modelState; + @Override - public void loadSourceModel(final RequestModelAction action, final GModelState modelState) { + public void loadSourceModel(final RequestModelAction action) { final File file = convertToFile(modelState); loadSourceModel(file, modelState).ifPresent(root -> { modelState.setRoot(root); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSourceLoader.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSourceLoader.java index 7dcef706..4ccd57ab 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSourceLoader.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSourceLoader.java @@ -15,7 +15,6 @@ ********************************************************************************/ package org.eclipse.glsp.server.features.core.model; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.utils.ClientOptionsUtil; /** @@ -36,8 +35,7 @@ public interface ModelSourceLoader { /** * Loads a source model into the modelState. * - * @param action Action sent by the client to specifying the information needed to load the source model. - * @param modelState The model state into which the source model shall be put. + * @param action Action sent by the client to specifying the information needed to load the source model. */ - void loadSourceModel(RequestModelAction action, GModelState modelState); + void loadSourceModel(RequestModelAction action); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSubmissionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSubmissionHandler.java index a75006f1..f5556732 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSubmissionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSubmissionHandler.java @@ -45,6 +45,9 @@ public class ModelSubmissionHandler { @Inject protected GModelFactory modelFactory; + @Inject + protected GModelState modelState; + private final Object modelLock = new Object(); /** @@ -52,14 +55,13 @@ public class ModelSubmissionHandler { *

* These actions are not processed by this {@link ModelSubmissionHandler}, but should be either manually dispatched * to the {@link ActionDispatcher}, or simply returned as the result of an - * {@link ActionHandler#execute(Action, GModelState)} method. + * {@link ActionHandler#execute(Action)} method. *

* - * @param modelState The model state to submit. - * @param reason The optional reason that caused the model update. + * @param reason The optional reason that caused the model update. * @return A list of actions to be processed in order to submit the model. */ - public List submitModel(final GModelState modelState, final String reason) { + public List submitModel(final String reason) { modelFactory.createGModel(modelState); modelState.getRoot().setRevision(modelState.getRoot().getRevision() + 1); boolean needsClientLayout = diagramConfiguration.needsClientLayout(); @@ -69,35 +71,34 @@ public List submitModel(final GModelState modelState, final String reaso new SetDirtyStateAction(modelState.isDirty(), reason)); } } - return submitModelDirectly(modelState, reason); + return submitModelDirectly(reason); } - public List submitModel(final GModelState modelState) { - return submitModel(modelState, null); + public List submitModel() { + return submitModel(null); } /** * Returns a list of actions to directly update the client-side model without any server- or client-side layouting. *

* Typically {@link ActionHandler action handlers} don't invoke this method but use - * {@link #submitModel(GModelState,String)} + * {@link #submitModel(String)} * instead, as this is only used to eventually submit the model on the client directly after all layouting is already * performed before. The only foreseen caller of this method is {@link ComputedBoundsActionHandler}. *

*

* These actions are not processed by this {@link ModelSubmissionHandler}, but should be either manually dispatched * to the {@link ActionDispatcher}, or simply returned as the result of an - * {@link ActionHandler#execute(Action, GModelState)} method. + * {@link ActionHandler#execute(Action)} method. *

* - * @param modelState The model state to submit. - * @param reason The optional reason that caused the model update. + * @param reason The optional reason that caused the model update. * @return A list of actions to be processed in order to submit the model. */ - public List submitModelDirectly(final GModelState modelState, final String reason) { + public List submitModelDirectly(final String reason) { GModelRoot gModel = modelState.getRoot(); if (diagramConfiguration.getLayoutKind() == ServerLayoutKind.AUTOMATIC && layoutEngine.isPresent()) { - layoutEngine.get().layout(modelState); + layoutEngine.get().layout(); } Action modelAction = gModel.getRevision() == 0 ? new SetModelAction(gModel) : new UpdateModelAction(gModel, diagramConfiguration.animatedUpdate()); @@ -111,8 +112,8 @@ public List submitModelDirectly(final GModelState modelState, final Stri } } - public List submitModelDirectly(final GModelState modelState) { - return submitModelDirectly(modelState, null); + public List submitModelDirectly() { + return submitModelDirectly(null); } public synchronized Object getModelLock() { return modelLock; } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/RequestModelActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/RequestModelActionHandler.java index e87c4279..2201ba4b 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/RequestModelActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/RequestModelActionHandler.java @@ -18,9 +18,9 @@ import java.util.List; import java.util.Optional; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; import org.eclipse.glsp.server.actions.ActionDispatcher; -import org.eclipse.glsp.server.actions.BasicActionHandler; import org.eclipse.glsp.server.features.modelsourcewatcher.ModelSourceWatcher; import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.utils.ServerMessageUtil; @@ -28,7 +28,7 @@ import com.google.inject.Inject; -public class RequestModelActionHandler extends BasicActionHandler { +public class RequestModelActionHandler extends AbstractActionHandler { @Inject protected ModelSourceLoader sourceModelLoader; @@ -42,25 +42,28 @@ public class RequestModelActionHandler extends BasicActionHandler executeAction(final RequestModelAction action, final GModelState modelState) { + public List executeAction(final RequestModelAction action) { modelState.setClientOptions(action.getOptions()); - notifyStartLoading(modelState); - sourceModelLoader.loadSourceModel(action, modelState); - notifyFinishedLoading(modelState); + notifyStartLoading(); + sourceModelLoader.loadSourceModel(action); + notifyFinishedLoading(); - modelSourceWatcher.ifPresent(watcher -> watcher.startWatching(modelState)); + modelSourceWatcher.ifPresent(watcher -> watcher.startWatching()); - return modelSubmissionHandler.submitModel(modelState); + return modelSubmissionHandler.submitModel(); } - protected void notifyStartLoading(final GModelState modelState) { + protected void notifyStartLoading() { actionDispatcher.dispatch(ServerStatusUtil.info("Model loading in progress!")); actionDispatcher.dispatch(ServerMessageUtil.info("Model loading in progress!")); } - protected void notifyFinishedLoading(final GModelState modelState) { + protected void notifyFinishedLoading() { actionDispatcher.dispatch(ServerStatusUtil.clear()); actionDispatcher.dispatch(ServerMessageUtil.clear()); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ApplyLabelEditOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ApplyLabelEditOperationHandler.java index f58eee49..d781a60e 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ApplyLabelEditOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ApplyLabelEditOperationHandler.java @@ -20,12 +20,17 @@ import org.eclipse.glsp.graph.GLabel; import org.eclipse.glsp.graph.GModelElement; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; -public class ApplyLabelEditOperationHandler extends BasicOperationHandler { +import com.google.inject.Inject; + +public class ApplyLabelEditOperationHandler extends AbstractOperationHandler { + + @Inject + protected GModelState modelState; @Override - public void executeOperation(final ApplyLabelEditOperation operation, final GModelState modelState) { + public void executeOperation(final ApplyLabelEditOperation operation) { Optional element = modelState.getIndex().get(operation.getLabelId()); if (!element.isPresent() && !(element.get() instanceof GLabel)) { throw new IllegalArgumentException("Element with provided ID cannot be found or is not a GLabel"); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ContextEditValidator.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ContextEditValidator.java index d076f11f..a979d6ff 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ContextEditValidator.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/ContextEditValidator.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -15,14 +15,11 @@ ********************************************************************************/ package org.eclipse.glsp.server.features.directediting; -import org.eclipse.glsp.server.model.GModelState; - public interface ContextEditValidator { String getContextId(); - ValidationStatus validate(RequestEditValidationAction action, - GModelState modelState); + ValidationStatus validate(RequestEditValidationAction action); default boolean handles(final String contextId) { return getContextId().equals(contextId); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/LabelEditValidator.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/LabelEditValidator.java index 586f970e..ab6c0b44 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/LabelEditValidator.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/LabelEditValidator.java @@ -16,11 +16,10 @@ package org.eclipse.glsp.server.features.directediting; import org.eclipse.glsp.graph.GModelElement; -import org.eclipse.glsp.server.model.GModelState; public interface LabelEditValidator { String CONTEXT_ID = "label-edit"; - ValidationStatus validate(GModelState modelState, String label, GModelElement element); + ValidationStatus validate(String label, GModelElement element); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/RequestEditValidationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/RequestEditValidationHandler.java index 733615f0..0b7b2193 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/RequestEditValidationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/directediting/RequestEditValidationHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -19,13 +19,12 @@ import java.util.Optional; import org.apache.log4j.Logger; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; -import org.eclipse.glsp.server.model.GModelState; import com.google.inject.Inject; -public class RequestEditValidationHandler extends BasicActionHandler { +public class RequestEditValidationHandler extends AbstractActionHandler { private static Logger log = Logger.getLogger(RequestEditValidationHandler.class); @@ -33,9 +32,9 @@ public class RequestEditValidationHandler extends BasicActionHandler executeAction(final RequestEditValidationAction action, final GModelState modelState) { + public List executeAction(final RequestEditValidationAction action) { Optional validationResult = contextEditValidatorRegistry.get(action.getContextId()) - .map(provider -> provider.validate(action, modelState)); + .map(provider -> provider.validate(action)); if (!validationResult.isPresent()) { String message = "No validator registered for the context '" + action.getContextId() + "'"; log.warn(message); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcher.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcher.java index 63565958..087bd38f 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcher.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcher.java @@ -51,6 +51,9 @@ public class FileWatcher implements ClientSessionListener, ModelSourceWatcher { @Inject protected ActionDispatcher actionDispatcher; + @Inject + protected GModelState modelState; + protected int debounceDelay = 500; protected final List workers = new ArrayList<>(); @@ -65,6 +68,12 @@ public FileWatcher(final ClientSessionManager sessionManager, final ActionDispat this.actionDispatcher = actionDispatcher; } + public FileWatcher(final ClientSessionManager sessionManager, final ActionDispatcher actionDispatcher, + final GModelState modelState) { + this(sessionManager, actionDispatcher); + this.modelState = modelState; + } + public int getDebounceDelay() { return debounceDelay; } public void setDebounceDelay(final int debounceDelay) { this.debounceDelay = debounceDelay; } @@ -75,26 +84,26 @@ public void sessionDisposed(final ClientSession session) { } @Override - public void startWatching(final GModelState modelState) { - start(modelState); + public void startWatching() { + start(); } @Override - public void stopWatching(final GModelState modelState) { + public void stopWatching() { disposeAllWorkers(); } @Override - public void pauseWatching(final GModelState modelState) { + public void pauseWatching() { workers.forEach(FileWatchWorker::pauseNotifications); } @Override - public void continueWatching(final GModelState modelState) { + public void continueWatching() { workers.forEach(FileWatchWorker::continueNotifications); } - protected void start(final GModelState modelState) { + protected void start() { IDisposable.disposeIfExists(clientNotificationDebouncer); clientNotificationDebouncer = new Debouncer<>(this::notifyClient, getDebounceDelay(), TimeUnit.MILLISECONDS); createWorkers(modelState).forEach(FileWatchWorker::start); @@ -105,7 +114,7 @@ protected void stop() { IDisposable.disposeIfExists(clientNotificationDebouncer); } - protected List getPaths(final GModelState modelState) { + protected List getPaths() { return ClientOptionsUtil.getSourceUriAsFile(modelState.getClientOptions()).stream() .map(file -> file.toPath()).collect(Collectors.toList()); } @@ -122,7 +131,8 @@ protected void disposeAllWorkers() { } private List createFileWatchWorkers(final GModelState modelState) { - return getPaths(modelState).stream().map(path -> new FileWatchWorker(modelState.getClientId(), path)) + return getPaths().stream() + .map(path -> new FileWatchWorker(modelState.getClientId(), path)) .collect(Collectors.toList()); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/ModelSourceWatcher.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/ModelSourceWatcher.java index e705b7e4..3858a1fe 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/ModelSourceWatcher.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/modelsourcewatcher/ModelSourceWatcher.java @@ -15,8 +15,6 @@ ********************************************************************************/ package org.eclipse.glsp.server.features.modelsourcewatcher; -import org.eclipse.glsp.server.model.GModelState; - /** * A model source watcher observes the model source and notifies the client if the model * source has changed. @@ -24,39 +22,31 @@ public interface ModelSourceWatcher { /** - * Starts watching the model source in the specified modelState. - * - * @param modelState The model state indicating the model source. + * Starts watching the model source. */ - default void startWatching(final GModelState modelState) {} + default void startWatching() {} /** - * Stops watching the model source in the specified modelState. + * Stops watching the model source. *

* If the watching hasn't been started before, this won't do anything. *

- * - * @param modelState The model state indicating the model source. */ - default void stopWatching(final GModelState modelState) {} + default void stopWatching() {} /** * Pauses the client notifications of this watcher. *

* If the watching hasn't been started before, this won't do anything. *

- * - * @param modelState The model state indicating the model source. */ - default void pauseWatching(final GModelState modelState) {} + default void pauseWatching() {} /** * Continues the client notifications of this watcher. *

* If the watching hasn't been started or paused before, this won't do anything. *

- * - * @param modelState The model state indicating the model source. */ - default void continueWatching(final GModelState modelState) {} + default void continueWatching() {} } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/NavigationTargetProvider.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/NavigationTargetProvider.java index 037fc5a2..fa0ab4ec 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/NavigationTargetProvider.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/NavigationTargetProvider.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -17,7 +17,6 @@ import java.util.List; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.types.EditorContext; public interface NavigationTargetProvider { @@ -40,10 +39,9 @@ public interface NavigationTargetProvider { * Other clients (non-Theia clients) should behave the same way. * * @param editorContext The editor context - * @param modelState The model state * @return the list of navigation targets */ - List getTargets(EditorContext editorContext, GModelState modelState); + List getTargets(EditorContext editorContext); String getTargetTypeId(); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/RequestNavigationTargetsActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/RequestNavigationTargetsActionHandler.java index 690861f7..f18987d4 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/RequestNavigationTargetsActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/RequestNavigationTargetsActionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -18,25 +18,23 @@ import java.util.ArrayList; import java.util.List; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.types.EditorContext; import com.google.inject.Inject; -public class RequestNavigationTargetsActionHandler extends BasicActionHandler { +public class RequestNavigationTargetsActionHandler extends AbstractActionHandler { @Inject protected NavigationTargetProviderRegistry navigationTargetProviderRegistry; @Override - public List executeAction(final RequestNavigationTargetsAction action, - final GModelState modelState) { + public List executeAction(final RequestNavigationTargetsAction action) { EditorContext editorContext = action.getEditorContext(); List allTargets = new ArrayList<>(); navigationTargetProviderRegistry.get(action.getTargetTypeId()) - .map(provider -> provider.getTargets(editorContext, modelState)) + .map(provider -> provider.getTargets(editorContext)) .ifPresent(targets -> allTargets.addAll(targets)); return listOf(new SetNavigationTargetsAction(allTargets, action.getEditorContext().getArgs())); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/ResolveNavigationTargetActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/ResolveNavigationTargetActionHandler.java index 9df7d3c4..86c0acda 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/ResolveNavigationTargetActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/navigation/ResolveNavigationTargetActionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -20,20 +20,23 @@ import org.apache.log4j.Logger; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.model.GModelState; import com.google.inject.Inject; -public class ResolveNavigationTargetActionHandler extends BasicActionHandler { +public class ResolveNavigationTargetActionHandler extends AbstractActionHandler { private static final Logger LOG = Logger.getLogger(ResolveNavigationTargetActionHandler.class); @Inject protected Optional navigationTargetResolver; + @Inject + protected GModelState modelState; + @Override - public List executeAction(final ResolveNavigationTargetAction action, final GModelState modelState) { + public List executeAction(final ResolveNavigationTargetAction action) { if (navigationTargetResolver.isEmpty()) { LOG.warn("Could not resolve navigation target. No implementation for: " + NavigationTargetResolver.class.getName() + " has been bound."); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/PopupModelFactory.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/PopupModelFactory.java index 1328163a..b7038e29 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/PopupModelFactory.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/PopupModelFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -19,10 +19,8 @@ import org.eclipse.glsp.graph.GHtmlRoot; import org.eclipse.glsp.graph.GModelElement; -import org.eclipse.glsp.server.model.GModelState; public interface PopupModelFactory { - Optional createPopupModel(GModelElement element, RequestPopupModelAction action, - GModelState modelState); + Optional createPopupModel(GModelElement element, RequestPopupModelAction action); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/RequestPopupModelActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/RequestPopupModelActionHandler.java index 6224f1e3..1fd44f3a 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/RequestPopupModelActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/popup/RequestPopupModelActionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -19,22 +19,25 @@ import java.util.Optional; import org.eclipse.glsp.graph.GModelElement; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; import org.eclipse.glsp.server.model.GModelState; import com.google.inject.Inject; -public class RequestPopupModelActionHandler extends BasicActionHandler { +public class RequestPopupModelActionHandler extends AbstractActionHandler { @Inject protected Optional popupModelFactory; + @Inject + protected GModelState modelState; + @Override - public List executeAction(final RequestPopupModelAction action, final GModelState modelState) { + public List executeAction(final RequestPopupModelAction action) { if (popupModelFactory.isPresent()) { Optional element = modelState.getIndex().get(action.getElementId()); if (popupModelFactory != null && element.isPresent()) { - return listOf(popupModelFactory.get().createPopupModel(element.get(), action, modelState) + return listOf(popupModelFactory.get().createPopupModel(element.get(), action) .map(popupModel -> new SetPopupModelAction(popupModel, action.getBounds()))); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/toolpalette/ToolPaletteItemProvider.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/toolpalette/ToolPaletteItemProvider.java index 39ef4be7..de74c2ef 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/toolpalette/ToolPaletteItemProvider.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/toolpalette/ToolPaletteItemProvider.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -20,7 +20,6 @@ import org.eclipse.glsp.server.features.contextactions.ContextActionsProvider; import org.eclipse.glsp.server.features.directediting.LabeledAction; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.types.EditorContext; public interface ToolPaletteItemProvider extends ContextActionsProvider { @@ -30,10 +29,9 @@ public interface ToolPaletteItemProvider extends ContextActionsProvider { default String getContextId() { return ToolPaletteItemProvider.CONTEXT_ID; } @Override - default List getActions(final EditorContext editorContext, - final GModelState modelState) { - return getItems(editorContext.getArgs(), modelState); + default List getActions(final EditorContext editorContext) { + return getItems(editorContext.getArgs()); } - List getItems(Map args, GModelState modelState); + List getItems(Map args); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/undoredo/UndoRedoActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/undoredo/UndoRedoActionHandler.java index adf739ad..a826ccb9 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/undoredo/UndoRedoActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/undoredo/UndoRedoActionHandler.java @@ -33,14 +33,17 @@ public class UndoRedoActionHandler implements ActionHandler { @Inject protected ModelSubmissionHandler modelSubmissionHandler; + @Inject + protected GModelState modelState; + @Override - public List execute(final Action action, final GModelState modelState) { + public List execute(final Action action) { if (action instanceof UndoAction && modelState.canUndo()) { modelState.undo(); - return modelSubmissionHandler.submitModel(modelState, SetDirtyStateAction.Reason.UNDO); + return modelSubmissionHandler.submitModel(SetDirtyStateAction.Reason.UNDO); } else if (action instanceof RedoAction && modelState.canRedo()) { modelState.redo(); - return modelSubmissionHandler.submitModel(modelState, SetDirtyStateAction.Reason.REDO); + return modelSubmissionHandler.submitModel(SetDirtyStateAction.Reason.REDO); } LOG.warn("Cannot undo or redo"); return none(); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/ModelValidator.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/ModelValidator.java index b205bbfa..ff97cf8e 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/ModelValidator.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/ModelValidator.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -18,9 +18,8 @@ import java.util.List; import org.eclipse.glsp.graph.GModelElement; -import org.eclipse.glsp.server.model.GModelState; public interface ModelValidator { - List validate(GModelState modelState, GModelElement... elements); + List validate(GModelElement... elements); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/RequestMarkersHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/RequestMarkersHandler.java index dbccd715..c6374168 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/RequestMarkersHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/validation/RequestMarkersHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -23,22 +23,25 @@ import org.apache.log4j.Logger; import org.eclipse.glsp.graph.GModelElement; import org.eclipse.glsp.graph.GModelIndex; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; import org.eclipse.glsp.server.model.GModelState; import com.google.inject.Inject; -public class RequestMarkersHandler extends BasicActionHandler { +public class RequestMarkersHandler extends AbstractActionHandler { private static final Logger LOG = Logger.getLogger(RequestMarkersHandler.class); @Inject protected Optional validator; + @Inject + protected GModelState modelState; + @Override @SuppressWarnings("checkstyle:cyclomaticComplexity") - public List executeAction(final RequestMarkersAction action, final GModelState modelState) { + public List executeAction(final RequestMarkersAction action) { List elementsIDs = action.getElementsIDs(); if (validator.isEmpty()) { LOG.warn("Cannot compute markers! No implementation for " + ModelValidator.class + " has been bound"); @@ -55,7 +58,7 @@ public List executeAction(final RequestMarkersAction action, final GMode for (String elementID : elementsIDs) { Optional modelElement = currentModelIndex.get(elementID); if (modelElement.isPresent()) { - markers.addAll(validator.get().validate(modelState, modelElement.get())); + markers.addAll(validator.get().validate(modelElement.get())); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/actions/DefaultActionDispatcher.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/actions/DefaultActionDispatcher.java index 8c47b53e..5c4a54b0 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/actions/DefaultActionDispatcher.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/actions/DefaultActionDispatcher.java @@ -36,7 +36,6 @@ import org.eclipse.glsp.server.actions.ResponseAction; import org.eclipse.glsp.server.di.ClientId; import org.eclipse.glsp.server.disposable.Disposable; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.protocol.GLSPClient; import org.eclipse.glsp.server.utils.FutureUtil; @@ -63,9 +62,6 @@ public class DefaultActionDispatcher extends Disposable implements ActionDispatc @ClientId protected String clientId; - @Inject - protected GModelState modelState; - protected final String name; protected final Thread thread; @@ -193,7 +189,7 @@ protected List> runAction(final Action action) { List> results = new ArrayList<>(); for (final ActionHandler actionHandler : actionHandlers) { - final List responses = actionHandler.execute(action, modelState).stream() + final List responses = actionHandler.execute(action).stream() .map(response -> ResponseAction.respond(action, response)) .collect(Collectors.toList()); results.addAll(dispatchAll(responses)); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/featues/directediting/DefaultContextEditValidatorRegistry.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/featues/directediting/DefaultContextEditValidatorRegistry.java index 3f087d00..8fafa1b3 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/featues/directediting/DefaultContextEditValidatorRegistry.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/featues/directediting/DefaultContextEditValidatorRegistry.java @@ -23,18 +23,18 @@ import org.eclipse.glsp.server.features.directediting.LabelEditValidator; import org.eclipse.glsp.server.internal.labeledit.ValidateLabelEditAdapter; import org.eclipse.glsp.server.internal.registry.MapRegistry; +import org.eclipse.glsp.server.model.GModelState; import com.google.inject.Inject; public class DefaultContextEditValidatorRegistry extends MapRegistry implements ContextEditValidatorRegistry { - @Inject public DefaultContextEditValidatorRegistry(final Set contextEditValidators, - final Optional labelEditValidator) { + final Optional labelEditValidator, final GModelState modelState) { contextEditValidators.forEach(provider -> register(provider.getContextId(), provider)); if (labelEditValidator.isPresent()) { - register(LabelEditValidator.CONTEXT_ID, new ValidateLabelEditAdapter(labelEditValidator.get())); + register(LabelEditValidator.CONTEXT_ID, new ValidateLabelEditAdapter(modelState, labelEditValidator.get())); } } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/labeledit/ValidateLabelEditAdapter.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/labeledit/ValidateLabelEditAdapter.java index 46dfe753..b7f8f52e 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/labeledit/ValidateLabelEditAdapter.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/labeledit/ValidateLabelEditAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -27,9 +27,11 @@ public class ValidateLabelEditAdapter implements ContextEditValidator { private final LabelEditValidator editLabelValidator; + private final GModelState modelState; - public ValidateLabelEditAdapter(final LabelEditValidator editLabelValidator) { + public ValidateLabelEditAdapter(final GModelState modelState, final LabelEditValidator editLabelValidator) { super(); + this.modelState = modelState; this.editLabelValidator = editLabelValidator; } @@ -37,10 +39,10 @@ public ValidateLabelEditAdapter(final LabelEditValidator editLabelValidator) { public String getContextId() { return LabelEditValidator.CONTEXT_ID; } @Override - public ValidationStatus validate(final RequestEditValidationAction action, final GModelState modelState) { + public ValidationStatus validate(final RequestEditValidationAction action) { Optional element = modelState.getIndex().get(action.getModelElementId()); if (element.isPresent()) { - return editLabelValidator.validate(modelState, action.getText(), element.get()); + return editLabelValidator.validate(action.getText(), element.get()); } return ValidationStatus.ok(); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/toolpalette/DefaultToolPaletteItemProvider.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/toolpalette/DefaultToolPaletteItemProvider.java index f6335ffd..e989481e 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/toolpalette/DefaultToolPaletteItemProvider.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/internal/toolpalette/DefaultToolPaletteItemProvider.java @@ -23,7 +23,6 @@ import org.eclipse.glsp.server.actions.TriggerElementCreationAction; import org.eclipse.glsp.server.features.toolpalette.PaletteItem; import org.eclipse.glsp.server.features.toolpalette.ToolPaletteItemProvider; -import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.operations.CreateEdgeOperation; import org.eclipse.glsp.server.operations.CreateNodeOperation; import org.eclipse.glsp.server.operations.CreateOperation; @@ -40,7 +39,7 @@ public class DefaultToolPaletteItemProvider implements ToolPaletteItemProvider { private int counter; @Override - public List getItems(final Map args, final GModelState modelState) { + public List getItems(final Map args) { List handlers = operationHandlerRegistry.getAll().stream() .filter(CreateOperationHandler.class::isInstance) .map(CreateOperationHandler.class::cast) diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/layout/LayoutEngine.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/layout/LayoutEngine.java index 8f9aeefc..81a94185 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/layout/LayoutEngine.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/layout/LayoutEngine.java @@ -15,16 +15,12 @@ ******************************************************************************/ package org.eclipse.glsp.server.layout; -import org.eclipse.glsp.server.model.GModelState; - /** * A layout engine is able to compute layout information for a model. */ public interface LayoutEngine { - /* - * Compute a layout for the given model and modify the model accordingly. + * Compute a layout for the model state and modify the model accordingly. */ - void layout(GModelState modelState); - + void layout(); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractCreateOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractCreateOperationHandler.java new file mode 100644 index 00000000..00569b85 --- /dev/null +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractCreateOperationHandler.java @@ -0,0 +1,59 @@ +/******************************************************************************** + * Copyright (c) 2020 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.operations; + +import java.util.List; + +import org.eclipse.glsp.server.internal.util.GenericsUtil; + +import com.google.common.collect.Lists; + +public abstract class AbstractCreateOperationHandler extends AbstractOperationHandler + implements CreateOperationHandler { + protected List handledElementTypeIds; + + public AbstractCreateOperationHandler(final String... elementTypeIds) { + this(Lists.newArrayList(elementTypeIds)); + } + + public AbstractCreateOperationHandler(final List handledElementTypeIds) { + this.handledElementTypeIds = handledElementTypeIds; + } + + @SuppressWarnings("unchecked") + @Override + protected Class deriveOperationType() { + return (Class) (GenericsUtil.getParametrizedType(getClass(), AbstractCreateOperationHandler.class)) + .getActualTypeArguments()[0]; + } + + @Override + public boolean handles(final Operation operation) { + return super.handles(operation) && handledElementTypeIds.contains(getHandledOperationType() + .cast(operation).getElementTypeId()); + } + + @Override + public abstract String getLabel(); + + @Override + public List getHandledElementTypeIds() { return handledElementTypeIds; } + + public void setHandledElementTypeIds(final List handledElementTypeIds) { + this.handledElementTypeIds = handledElementTypeIds; + } + +} diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractOperationHandler.java new file mode 100644 index 00000000..173eba3b --- /dev/null +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/AbstractOperationHandler.java @@ -0,0 +1,57 @@ +/******************************************************************************** + * Copyright (c) 2020-2021 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.operations; + +import org.eclipse.glsp.server.internal.util.GenericsUtil; + +/** + * Basic {@link OperationHandler} implementation that can handle exactly one {@link Operation} type. + * It handles the overhead of casting the operation object received via the {@link OperationHandler#execute(Operation)} + * method to the correct handled subtype. Subclasses only have to implement the + * {@link AbstractOperationHandler#executeOperation(Operation)} method + * and can work directly with the correct subtype instead of having to manually cast it. + * + * @param class of the handled action type + */ +public abstract class AbstractOperationHandler implements OperationHandler { + + protected final Class operationType; + + public AbstractOperationHandler() { + this.operationType = deriveOperationType(); + } + + @SuppressWarnings("unchecked") + protected Class deriveOperationType() { + return (Class) (GenericsUtil.getParametrizedType(getClass(), AbstractOperationHandler.class)) + .getActualTypeArguments()[0]; + } + + @Override + public Class getHandledOperationType() { return operationType; } + + @Override + public void execute(final Operation operation) { + if (handles(operation)) { + executeOperation(operationType.cast(operation)); + } + } + + protected abstract void executeOperation(O operation); + + @Override + public String getLabel() { return operationType.getSimpleName(); } +} diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicCreateOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicCreateOperationHandler.java index 0fa68565..c5974582 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicCreateOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicCreateOperationHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -18,13 +18,20 @@ import java.util.List; import org.eclipse.glsp.server.internal.util.GenericsUtil; +import org.eclipse.glsp.server.model.GModelState; import com.google.common.collect.Lists; +import com.google.inject.Inject; -public abstract class BasicCreateOperationHandler extends BasicOperationHandler - implements CreateOperationHandler { +/** + * Deprecated, will be removed with version 1.0. + * Please use {@link AbstractCreateOperationHandler} instead and directly inject the {@link GModelState}. + */ +@Deprecated +public abstract class BasicCreateOperationHandler extends AbstractCreateOperationHandler { - private List handledElementTypeIds; + @Inject + protected GModelState modelState; public BasicCreateOperationHandler(final String... elementTypeIds) { this(Lists.newArrayList(elementTypeIds)); @@ -42,19 +49,10 @@ protected Class deriveOperationType() { } @Override - public boolean handles(final Operation operation) { - return super.handles(operation) && handledElementTypeIds.contains(getHandledOperationType() - .cast(operation).getElementTypeId()); + protected void executeOperation(final T operation) { + executeOperation(operation, modelState); } - @Override - public abstract String getLabel(); - - @Override - public List getHandledElementTypeIds() { return handledElementTypeIds; } - - public void setHandledElementTypeIds(final List handledElementTypeIds) { - this.handledElementTypeIds = handledElementTypeIds; - } + protected abstract void executeOperation(T operation, GModelState modelState); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicOperationHandler.java index 77e8f109..74dbf539 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/BasicOperationHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -18,32 +18,30 @@ import org.eclipse.glsp.server.internal.util.GenericsUtil; import org.eclipse.glsp.server.model.GModelState; -public abstract class BasicOperationHandler implements OperationHandler { +import com.google.inject.Inject; - protected final Class operationType; +/** + * Deprecated, will be removed with version 1.0. + * Please use {@link AbstractOperationHandler} instead and directly inject the {@link GModelState}. + */ +@Deprecated +public abstract class BasicOperationHandler extends AbstractOperationHandler { - public BasicOperationHandler() { - this.operationType = deriveOperationType(); + @Inject + protected GModelState modelState; + + @Override + protected void executeOperation(final T operation) { + executeOperation(operation, modelState); } + @Override @SuppressWarnings("unchecked") protected Class deriveOperationType() { return (Class) (GenericsUtil.getParametrizedType(getClass(), BasicOperationHandler.class)) .getActualTypeArguments()[0]; } - @Override - public Class getHandledOperationType() { return operationType; } - - @Override - public void execute(final Operation operation, final GModelState modelState) { - if (handles(operation)) { - executeOperation(operationType.cast(operation), modelState); - } - } - protected abstract void executeOperation(T operation, GModelState modelState); - @Override - public String getLabel() { return operationType.getSimpleName(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/Operation.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/Operation.java index 81976499..f71df60a 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/Operation.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/Operation.java @@ -20,6 +20,8 @@ /** * * An Operation is an {@link Action} that directly manipulates the model representation on server side. + * Operations are handled by instances of {@link OperationHandler}. The operation handler is responsible + * of processing the operation and updates the model representation accordingly. * */ public abstract class Operation extends Action { diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationActionHandler.java index 657a5e9f..413b89da 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationActionHandler.java @@ -18,8 +18,8 @@ import java.util.List; import java.util.Optional; +import org.eclipse.glsp.server.actions.AbstractActionHandler; import org.eclipse.glsp.server.actions.Action; -import org.eclipse.glsp.server.actions.BasicActionHandler; import org.eclipse.glsp.server.actions.SetDirtyStateAction; import org.eclipse.glsp.server.features.core.model.ModelSubmissionHandler; import org.eclipse.glsp.server.internal.gmodel.commandstack.GModelRecordingCommand; @@ -28,37 +28,40 @@ import com.google.inject.Inject; -public class OperationActionHandler extends BasicActionHandler { +public class OperationActionHandler extends AbstractActionHandler { + @Inject protected OperationHandlerRegistry operationHandlerRegistry; @Inject protected ModelSubmissionHandler modelSubmissionHandler; + @Inject + protected GModelState modelState; + @Override public boolean handles(final Action action) { return action instanceof Operation; } @Override - public List executeAction(final Operation operation, final GModelState modelState) { + public List executeAction(final Operation operation) { if (modelState.isReadonly()) { return listOf(ServerMessageUtil .warn("Server is in readonly-mode! Could not execute operation: " + operation.getKind())); } Optional operationHandler = getOperationHandler(operation, operationHandlerRegistry); if (operationHandler.isPresent()) { - return executeHandler(operation, operationHandler.get(), modelState); + return executeHandler(operation, operationHandler.get()); } return none(); } - protected List executeHandler(final Operation operation, final OperationHandler handler, - final GModelState modelState) { + protected List executeHandler(final Operation operation, final OperationHandler handler) { GModelRecordingCommand command = new GModelRecordingCommand(modelState.getRoot(), handler.getLabel(), - () -> handler.execute(operation, modelState)); + () -> handler.execute(operation)); modelState.execute(command); - return modelSubmissionHandler.submitModel(modelState, SetDirtyStateAction.Reason.OPERATION); + return modelSubmissionHandler.submitModel(SetDirtyStateAction.Reason.OPERATION); } public static Optional getOperationHandler(final Operation operation, diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationHandler.java index 53778642..41f4599c 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/OperationHandler.java @@ -15,20 +15,52 @@ ******************************************************************************/ package org.eclipse.glsp.server.operations; +import org.eclipse.emf.common.command.Command; +import org.eclipse.glsp.server.actions.ActionDispatcher; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.types.Handler; +import org.eclipse.glsp.server.types.GLSPServerException; -public interface OperationHandler extends Handler { +/** + * An operation handler can execute {@link Operation}s of a certain type (subclass). + * The operation handler processes the operation in the {@link OperationHandler#execute(Operation)} method. The result + * of the execution is an update of the {@link GModelState} state. + * This update is reversible (undo) and can be reapplied (redo). For basic diagram languages these updates are typically + * applied directly on the {@link GModelState} using EMF {@link Command}s and the + * {@link GModelState#execute(org.eclipse.emf.common.command.Command)} method. For more complex diagram languages the + * GModel state might be updated indirectly and the operation handler manipulates a custom model representation. + * + * The {@link OperationActionHandler} is responsible for retrieving all available (valid) operation handlers for an + * operation that is dispatched via {@link ActionDispatcher}. + */ +public interface OperationHandler { + /** + * Returns the class of the operation type that can be handled by this operation handler. + * + * @return the {@link Operation} (sub)class that can be handled. + */ Class getHandledOperationType(); String getLabel(); - void execute(Operation operation, GModelState modelState); + /** + * Executes the operation handler for the given {@link Operation} If the given action cannot be handled by this + * operation handler a {@link GLSPServerException} is thrown. + * + * @param operation The operation that should be executed. + */ + void execute(Operation operation); - @Override + /** + * Validates whether the given {@link Operation} can be handled by this operation handler. + * The default implementation the handled operation type ({@link OperationHandler#getHandledOperationType()} + * to determine whether this handler can handle an operation. Only operations that are instances of these operation + * type class can be handled. + * + * @param operation The operation that should be validated. + * @return `true` if the given operation can be handled, `false` otherwise. + */ default boolean handles(final Operation operation) { return getHandledOperationType().isInstance(operation); } - } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeBoundsOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeBoundsOperationHandler.java index 7c46eae7..7e0caf89 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeBoundsOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeBoundsOperationHandler.java @@ -27,26 +27,30 @@ import org.eclipse.glsp.graph.builder.impl.GLayoutOptions; import org.eclipse.glsp.graph.util.GraphUtil; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; import org.eclipse.glsp.server.operations.ChangeBoundsOperation; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.types.ElementAndBounds; +import com.google.inject.Inject; + /** * Generic handler implementation for {@link ChangeBoundsOperation}. */ -public class ChangeBoundsOperationHandler extends BasicOperationHandler { +public class ChangeBoundsOperationHandler extends AbstractOperationHandler { private static Logger log = Logger.getLogger(ChangeBoundsOperationHandler.class); + @Inject + protected GModelState modelState; + @Override - public void executeOperation(final ChangeBoundsOperation operation, final GModelState modelState) { + public void executeOperation(final ChangeBoundsOperation operation) { for (ElementAndBounds element : operation.getNewBounds()) { - changeElementBounds(element.getElementId(), element.getNewPosition(), element.getNewSize(), modelState); + changeElementBounds(element.getElementId(), element.getNewPosition(), element.getNewSize()); } } - private void changeElementBounds(final String elementId, final GPoint newPosition, final GDimension newSize, - final GModelState modelState) { + protected void changeElementBounds(final String elementId, final GPoint newPosition, final GDimension newSize) { if (elementId == null) { log.warn("Invalid ChangeBounds Action; missing mandatory arguments"); return; diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeRoutingPointsHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeRoutingPointsHandler.java index 49bcb97b..a26ca6ac 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeRoutingPointsHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ChangeRoutingPointsHandler.java @@ -22,14 +22,19 @@ import org.eclipse.glsp.graph.GModelIndex; import org.eclipse.glsp.graph.GPoint; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; import org.eclipse.glsp.server.operations.ChangeRoutingPointsOperation; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.types.ElementAndRoutingPoints; -public class ChangeRoutingPointsHandler extends BasicOperationHandler { +import com.google.inject.Inject; + +public class ChangeRoutingPointsHandler extends AbstractOperationHandler { + + @Inject + protected GModelState modelState; @Override - protected void executeOperation(final ChangeRoutingPointsOperation operation, final GModelState modelState) { + protected void executeOperation(final ChangeRoutingPointsOperation operation) { // check for null-values if (operation.getNewRoutingPoints() == null) { diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CompoundOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CompoundOperationHandler.java index e235a68e..0b27852f 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CompoundOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CompoundOperationHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -17,9 +17,8 @@ import java.util.Optional; -import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; import org.eclipse.glsp.server.operations.CompoundOperation; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.operations.Operation; import org.eclipse.glsp.server.operations.OperationActionHandler; import org.eclipse.glsp.server.operations.OperationHandler; @@ -27,20 +26,20 @@ import com.google.inject.Inject; -public class CompoundOperationHandler extends BasicOperationHandler { +public class CompoundOperationHandler extends AbstractOperationHandler { @Inject protected OperationHandlerRegistry operationHandlerRegistry; @Override - protected void executeOperation(final CompoundOperation operation, final GModelState modelState) { - operation.getOperationList().forEach(nestedOperation -> executeNestedOperation(nestedOperation, modelState)); + protected void executeOperation(final CompoundOperation operation) { + operation.getOperationList().forEach(nestedOperation -> executeNestedOperation(nestedOperation)); } - protected void executeNestedOperation(final Operation operation, final GModelState modelState) { + protected void executeNestedOperation(final Operation operation) { Optional operationHandler = OperationActionHandler.getOperationHandler(operation, operationHandlerRegistry); if (operationHandler.isPresent()) { - operationHandler.get().execute(operation, modelState); + operationHandler.get().execute(operation); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateEdgeOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateEdgeOperationHandler.java index c527a8bb..a016fe92 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateEdgeOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateEdgeOperationHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -24,12 +24,17 @@ import org.eclipse.glsp.graph.GModelIndex; import org.eclipse.glsp.graph.GModelRoot; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicCreateOperationHandler; import org.eclipse.glsp.server.operations.CreateEdgeOperation; +import org.eclipse.glsp.server.operations.AbstractCreateOperationHandler; -public abstract class CreateEdgeOperationHandler extends BasicCreateOperationHandler { +import com.google.inject.Inject; - private final String label; +public abstract class CreateEdgeOperationHandler extends AbstractCreateOperationHandler { + + protected final String label; + + @Inject + protected GModelState modelState; public CreateEdgeOperationHandler(final String elementTypeId, final String label) { super(elementTypeId); @@ -37,18 +42,18 @@ public CreateEdgeOperationHandler(final String elementTypeId, final String label } @Override - public void executeOperation(final CreateEdgeOperation action, final GModelState modelState) { - if (action.getSourceElementId() == null || action.getTargetElementId() == null) { + public void executeOperation(final CreateEdgeOperation operation) { + if (operation.getSourceElementId() == null || operation.getTargetElementId() == null) { throw new IllegalArgumentException("Incomplete create connection action"); } GModelIndex index = modelState.getIndex(); - Optional source = index.findElement(action.getSourceElementId(), IS_CONNECTABLE); - Optional target = index.findElement(action.getTargetElementId(), IS_CONNECTABLE); + Optional source = index.findElement(operation.getSourceElementId(), IS_CONNECTABLE); + Optional target = index.findElement(operation.getTargetElementId(), IS_CONNECTABLE); if (!source.isPresent() || !target.isPresent()) { - throw new IllegalArgumentException("Invalid source or target for source ID " + action.getSourceElementId() - + " and target ID " + action.getTargetElementId()); + throw new IllegalArgumentException("Invalid source or target for source ID " + operation.getSourceElementId() + + " and target ID " + operation.getTargetElementId()); } Optional connection = createEdge(source.get(), target.get(), modelState); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateNodeOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateNodeOperationHandler.java index 44cfe1a2..452ffb5d 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateNodeOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CreateNodeOperationHandler.java @@ -26,27 +26,32 @@ import org.eclipse.glsp.graph.GPoint; import org.eclipse.glsp.graph.util.GraphUtil; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicCreateOperationHandler; import org.eclipse.glsp.server.operations.CreateNodeOperation; +import org.eclipse.glsp.server.operations.AbstractCreateOperationHandler; import org.eclipse.glsp.server.utils.GeometryUtil; -public abstract class CreateNodeOperationHandler extends BasicCreateOperationHandler { +import com.google.inject.Inject; + +public abstract class CreateNodeOperationHandler extends AbstractCreateOperationHandler { + + @Inject + protected GModelState modelState; public CreateNodeOperationHandler(final String elementTypeId) { super(elementTypeId); } @Override - public void executeOperation(final CreateNodeOperation operation, final GModelState modelState) { + public void executeOperation(final CreateNodeOperation operation) { - Optional container = getContainer(operation, modelState); + Optional container = getContainer(operation); if (!container.isPresent()) { container = Optional.of(modelState.getRoot()); } Optional absoluteLocation = getLocation(operation); Optional relativeLocation = getRelativeLocation(operation, absoluteLocation, container); - GModelElement element = createNode(relativeLocation, operation.getArgs(), modelState); + GModelElement element = createNode(relativeLocation, operation.getArgs()); container.get().getChildren().add(element); } @@ -58,11 +63,10 @@ public void executeOperation(final CreateNodeOperation operation, final GModelSt *

* * @param operation - * @param modelState * @return * the GModelElement that will contain the newly created node. */ - protected Optional getContainer(final CreateNodeOperation operation, final GModelState modelState) { + protected Optional getContainer(final CreateNodeOperation operation) { GModelIndex index = modelState.getIndex(); return index.get(operation.getContainerId()); } @@ -117,10 +121,8 @@ protected Optional getRelativeLocation(final CreateNodeOperation operati * * @param relativeLocation * @param args - * @param modelState * @return * The created {@link GNode Node}. */ - protected abstract GNode createNode(Optional relativeLocation, Map args, - GModelState modelState); + protected abstract GNode createNode(Optional relativeLocation, Map args); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CutOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CutOperationHandler.java index 3e33c0a6..c068022a 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CutOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/CutOperationHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020 EclipseSource and others. + * Copyright (c) 2020-2021 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 @@ -18,28 +18,26 @@ import java.util.List; import org.eclipse.glsp.server.actions.ActionDispatcher; -import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; import org.eclipse.glsp.server.operations.CutOperation; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.operations.DeleteOperation; import com.google.inject.Inject; -public class CutOperationHandler extends BasicOperationHandler { +public class CutOperationHandler extends AbstractOperationHandler { @Inject protected ActionDispatcher actionDispatcher; @Override - public void executeOperation(final CutOperation operation, final GModelState modelState) { - List cutableElementIds = getElementToCut(operation, modelState); + public void executeOperation(final CutOperation operation) { + List cutableElementIds = getElementToCut(operation); if (!cutableElementIds.isEmpty()) { actionDispatcher.dispatch(new DeleteOperation(cutableElementIds)); } } - protected List getElementToCut(final CutOperation cutAction, - final GModelState modelState) { + protected List getElementToCut(final CutOperation cutAction) { return cutAction.getEditorContext().getSelectedElementIds(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/DeleteOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/DeleteOperationHandler.java index fb27cc15..8fe819f8 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/DeleteOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/DeleteOperationHandler.java @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2019 EclipseSource and others. + * Copyright (c) 2019-2021 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 @@ -29,18 +29,23 @@ import org.eclipse.glsp.graph.GModelIndex; import org.eclipse.glsp.graph.GNode; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.operations.DeleteOperation; +import com.google.inject.Inject; + /** * Generic handler implementation for {@link DeleteOperation}. */ -public class DeleteOperationHandler extends BasicOperationHandler { +public class DeleteOperationHandler extends AbstractOperationHandler { private static Logger log = Logger.getLogger(DeleteOperationHandler.class); - private Set allDependantsIds; + protected Set allDependantsIds; + + @Inject + protected GModelState modelState; @Override - public void executeOperation(final DeleteOperation operation, final GModelState modelState) { + public void executeOperation(final DeleteOperation operation) { List elementIds = operation.getElementIds(); if (elementIds == null || elementIds.size() == 0) { log.warn("Elements to delete are not specified"); @@ -48,13 +53,13 @@ public void executeOperation(final DeleteOperation operation, final GModelState } GModelIndex index = modelState.getIndex(); allDependantsIds = new HashSet<>(); - boolean success = elementIds.stream().allMatch(eId -> delete(eId, index, modelState)); + boolean success = elementIds.stream().allMatch(eId -> delete(eId, index)); if (!success) { log.warn("Could not delete all elements as requested (see messages above to find out why)"); } } - protected boolean delete(final String elementId, final GModelIndex index, final GModelState modelState) { + protected boolean delete(final String elementId, final GModelIndex index) { if (allDependantsIds.contains(elementId)) { // The element as already been deleted as dependent of a previously deleted // element diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/LayoutOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/LayoutOperationHandler.java index b1edab0b..9a8040fc 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/LayoutOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/LayoutOperationHandler.java @@ -18,23 +18,23 @@ import org.eclipse.glsp.server.diagram.DiagramConfiguration; import org.eclipse.glsp.server.layout.LayoutEngine; import org.eclipse.glsp.server.layout.ServerLayoutKind; -import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.operations.LayoutOperation; import com.google.inject.Inject; -public class LayoutOperationHandler extends BasicOperationHandler { +public class LayoutOperationHandler extends AbstractOperationHandler { @Inject protected LayoutEngine layoutEngine; + @Inject protected DiagramConfiguration diagramConfiguration; @Override - protected void executeOperation(final LayoutOperation action, final GModelState modelState) { + protected void executeOperation(final LayoutOperation action) { if (diagramConfiguration.getLayoutKind() == ServerLayoutKind.MANUAL) { if (layoutEngine != null) { - layoutEngine.layout(modelState); + layoutEngine.layout(); } } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/PasteOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/PasteOperationHandler.java index 39923f8b..71769754 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/PasteOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/PasteOperationHandler.java @@ -34,17 +34,20 @@ import org.eclipse.glsp.graph.impl.GPointImpl; import org.eclipse.glsp.server.gson.GraphGsonConfigurationFactory; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.operations.PasteOperation; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.inject.Inject; -public class PasteOperationHandler extends BasicOperationHandler { +public class PasteOperationHandler extends AbstractOperationHandler { private static final int DEFAULT_OFFSET = 20; + @Inject + protected GModelState modelState; + protected final Gson gson; @Inject @@ -54,7 +57,7 @@ public PasteOperationHandler(final GraphGsonConfigurationFactory gsonConfigurato } @Override - public void executeOperation(final PasteOperation operation, final GModelState modelState) { + public void executeOperation(final PasteOperation operation) { List elements = getCopiedElements(operation.getClipboardData().get("application/json")); shift(elements, computeOffset(elements, operation.getEditorContext().getLastMousePosition())); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ReconnectEdgeOperationHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ReconnectEdgeOperationHandler.java index 5defaa9e..46a5d97b 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ReconnectEdgeOperationHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/operations/gmodel/ReconnectEdgeOperationHandler.java @@ -22,13 +22,19 @@ import org.eclipse.glsp.graph.GModelElement; import org.eclipse.glsp.graph.GModelIndex; import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.operations.BasicOperationHandler; +import org.eclipse.glsp.server.operations.AbstractOperationHandler; import org.eclipse.glsp.server.operations.ReconnectEdgeOperation; -public class ReconnectEdgeOperationHandler extends BasicOperationHandler { +import com.google.inject.Inject; + +public class ReconnectEdgeOperationHandler extends AbstractOperationHandler { + + @Inject + protected GModelState modelState; + @Override @SuppressWarnings("checkstyle:CyclomaticComplexity") - public void executeOperation(final ReconnectEdgeOperation operation, final GModelState modelState) { + public void executeOperation(final ReconnectEdgeOperation operation) { if (operation.getEdgeElementId() == null || operation.getSourceElementId() == null || operation.getTargetElementId() == null) { diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/types/Handler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/types/Handler.java deleted file mode 100644 index 2fdf7d04..00000000 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/types/Handler.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019-2021 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.types; - -public interface Handler { - - default int getPriority() { return Integer.MIN_VALUE; } - - boolean handles(T object); - -} diff --git a/tests/org.eclipse.glsp.server.test/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcherTest.java b/tests/org.eclipse.glsp.server.test/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcherTest.java index 515faf81..be68f89f 100644 --- a/tests/org.eclipse.glsp.server.test/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcherTest.java +++ b/tests/org.eclipse.glsp.server.test/src/org/eclipse/glsp/server/features/modelsourcewatcher/FileWatcherTest.java @@ -76,13 +76,13 @@ void changingWatchedFileNotifiesClient() final File file = createFile("test.txt"); final GModelState modelState = modelState("1", fileUri(file)); - final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher); + final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher, modelState); fileWatcher.setDebounceDelay(0); - fileWatcher.startWatching(modelState); + fileWatcher.startWatching(); sleep(); changeFile(file); sleep(); - fileWatcher.stopWatching(modelState); + fileWatcher.stopWatching(); assertNotifications(1); } @@ -93,13 +93,13 @@ void deletingWatchedFileNotifiesClient() final File file = createFile("test.txt"); final GModelState modelState = modelState("1", fileUri(file)); - final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher); + final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher, modelState); fileWatcher.setDebounceDelay(0); - fileWatcher.startWatching(modelState); + fileWatcher.startWatching(); sleep(); deleteFile(file); sleep(); - fileWatcher.stopWatching(modelState); + fileWatcher.stopWatching(); assertNotifications(1); } @@ -110,15 +110,15 @@ void changingWatchedFileWhilePausedDoesntNotifyClient() final File file = createFile("test.txt"); final GModelState modelState = modelState("1", fileUri(file)); - final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher); + final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher, modelState); fileWatcher.setDebounceDelay(0); - fileWatcher.startWatching(modelState); + fileWatcher.startWatching(); sleep(); - fileWatcher.pauseWatching(modelState); + fileWatcher.pauseWatching(); sleep(); changeFile(file); sleep(); - fileWatcher.stopWatching(modelState); + fileWatcher.stopWatching(); assertNoNotification(); } @@ -129,17 +129,17 @@ void changingWatchedFileAfterPauseAndContinueNotifiesClient() final File file = createFile("test.txt"); final GModelState modelState = modelState("1", fileUri(file)); - final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher); + final FileWatcher fileWatcher = new FileWatcher(sessionManager, actionDispatcher, modelState); fileWatcher.setDebounceDelay(0); - fileWatcher.startWatching(modelState); + fileWatcher.startWatching(); sleep(); - fileWatcher.pauseWatching(modelState); + fileWatcher.pauseWatching(); sleep(); - fileWatcher.continueWatching(modelState); + fileWatcher.continueWatching(); sleep(); changeFile(file); sleep(); - fileWatcher.stopWatching(modelState); + fileWatcher.stopWatching(); assertNotifications(1); }