diff --git a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/Action.java b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/Action.java index 50b3b17b..b1407672 100644 --- a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/Action.java +++ b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/Action.java @@ -109,6 +109,7 @@ public static class Kind { public static final String EXECUTE_SERVER_COMMAND = "executeServerCommand"; public static final String REQUEST_CONTEXT_ACTIONS = "requestContextActions"; public static final String SET_CONTEXT_ACTIONS = "setContextActions"; + public static final String SET_DIRTY_STATE = "setDirtyState"; public static final String REQUEST_MARKERS = "requestMarkers"; public static final String SET_MARKERS = "setMarkers"; public static final String LAYOUT = "layout"; diff --git a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/ActionProcessor.java b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/ActionProcessor.java index b085edeb..b467067d 100644 --- a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/ActionProcessor.java +++ b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/ActionProcessor.java @@ -15,9 +15,10 @@ ********************************************************************************/ package org.eclipse.glsp.api.action; -import java.util.Optional; +import static org.eclipse.glsp.api.action.kind.ResponseAction.respond; -import org.eclipse.glsp.api.action.kind.ResponseAction; +import java.util.Collections; +import java.util.List; public interface ActionProcessor { @@ -31,11 +32,8 @@ public interface ActionProcessor { * @param action The action to process */ default void process(final String clientId, final Action action) { - Optional responseOpt = dispatch(clientId, action); - if (responseOpt.isPresent()) { - // ensure request and response have same id if necessary - Action response = ResponseAction.respond(action, responseOpt.get()); - send(clientId, response); + for (Action responseAction : dispatch(clientId, action)) { + send(clientId, respond(action, responseAction)); } } @@ -59,7 +57,7 @@ default void process(final ActionMessage message) { * @return An optional Action to be sent to the client as the result of handling * the received action */ - Optional dispatch(String clientId, Action action); + List dispatch(String clientId, Action action); /** * Send the given action to the specified clientId. @@ -72,8 +70,8 @@ default void process(final ActionMessage message) { class NullImpl implements ActionProcessor { @Override - public Optional dispatch(final String clientId, final Action action) { - return Optional.empty(); + public List dispatch(final String clientId, final Action action) { + return Collections.emptyList(); } @Override diff --git a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/kind/SetDirtyStateAction.java b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/kind/SetDirtyStateAction.java new file mode 100644 index 00000000..a11aeddd --- /dev/null +++ b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/action/kind/SetDirtyStateAction.java @@ -0,0 +1,63 @@ +/******************************************************************************** + * 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.api.action.kind; + +import org.eclipse.glsp.api.action.Action; + +public class SetDirtyStateAction extends Action { + + private boolean isDirty; + + public SetDirtyStateAction() { + super(Action.Kind.SET_DIRTY_STATE); + } + + public SetDirtyStateAction(final boolean isDirty) { + this(); + this.isDirty = isDirty; + } + + public boolean isDirty() { return isDirty; } + + public void setDirty(final boolean isDirty) { this.isDirty = isDirty; } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (isDirty ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + SetDirtyStateAction other = (SetDirtyStateAction) obj; + if (isDirty != other.isDirty) { + return false; + } + return true; + } + +} diff --git a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ActionHandler.java b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ActionHandler.java index d48f42d7..86e861d6 100644 --- a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ActionHandler.java +++ b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ActionHandler.java @@ -15,12 +15,30 @@ ********************************************************************************/ package org.eclipse.glsp.api.handler; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Optional; import org.eclipse.glsp.api.action.Action; public interface ActionHandler extends Handler { - Optional execute(String clientId, Action action); + List execute(String clientId, Action action); + + default List listOf(final Action... action) { + return Arrays.asList(action); + } + + default List listOf(final Optional optionalAction) { + List actions = new ArrayList<>(); + optionalAction.ifPresent(action -> actions.add(action)); + return actions; + } + + default List none() { + return Collections.emptyList(); + } } diff --git a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ServerCommandHandler.java b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ServerCommandHandler.java index 735ee1ab..14be6994 100644 --- a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ServerCommandHandler.java +++ b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/handler/ServerCommandHandler.java @@ -16,8 +16,8 @@ package org.eclipse.glsp.api.handler; import java.util.Collections; +import java.util.List; import java.util.Map; -import java.util.Optional; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.model.GraphicalModelState; @@ -28,5 +28,5 @@ default void execute(final String commandId, final GraphicalModelState modelStat execute(commandId, Collections.emptyMap(), modelState); } - Optional execute(String commandId, Map options, GraphicalModelState modelState); + List execute(String commandId, Map options, GraphicalModelState modelState); } diff --git a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/model/ModelState.java b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/model/ModelState.java index 37ea17e6..b75eeee5 100644 --- a/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/model/ModelState.java +++ b/plugins/org.eclipse.glsp.api/src/org/eclipse/glsp/api/model/ModelState.java @@ -37,4 +37,8 @@ public interface ModelState { void redo(); + boolean isDirty(); + + void saveIsDone(); + } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/AbstractActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/AbstractActionHandler.java index b2b4b13a..26356e31 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/AbstractActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/AbstractActionHandler.java @@ -15,6 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.List; import java.util.Optional; import org.eclipse.glsp.api.action.Action; @@ -37,7 +38,7 @@ public abstract class AbstractActionHandler implements ActionHandler { * the client. If no response to the client is need a NoOpAction is returned */ @Override - public Optional execute(final String clientId, final Action action) { + public List execute(final String clientId, final Action action) { this.clientId = clientId; Optional modelState = modelStateProvider.getModelState(clientId); if (modelState.isPresent()) { @@ -45,8 +46,8 @@ public Optional execute(final String clientId, final Action action) { } ServerStatus status = new ServerStatus(Severity.FATAL, "Could not retrieve the model state for client with id '" + clientId + "'"); - return Optional.of(new ServerStatusAction(status)); + return listOf(new ServerStatusAction(status)); } - protected abstract Optional execute(Action action, GraphicalModelState modelState); + protected abstract List execute(Action action, GraphicalModelState modelState); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/CollapseExpandActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/CollapseExpandActionHandler.java index ed43a6a2..a912bfec 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/CollapseExpandActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/CollapseExpandActionHandler.java @@ -15,7 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.List; import java.util.Set; import org.eclipse.glsp.api.action.Action; @@ -36,18 +36,18 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { switch (action.getKind()) { case Action.Kind.COLLAPSE_EXPAND: return handleCollapseExpandAction((CollapseExpandAction) action, modelState); case Action.Kind.COLLAPSE_EXPAND_ALL: return handleCollapseExpandAllAction((CollapseExpandAllAction) action, modelState); default: - return Optional.empty(); + return none(); } } - private Optional handleCollapseExpandAllAction(final CollapseExpandAllAction action, + private List handleCollapseExpandAllAction(final CollapseExpandAllAction action, final GraphicalModelState modelState) { Set expandedElements = modelState.getExpandedElements(); expandedElements.clear(); @@ -57,10 +57,10 @@ private Optional handleCollapseExpandAllAction(final CollapseExpandAllAc if (expansionListener != null) { expansionListener.expansionChanged(action); } - return Optional.empty(); + return none(); } - private Optional handleCollapseExpandAction(final CollapseExpandAction action, + private List handleCollapseExpandAction(final CollapseExpandAction action, final GraphicalModelState modelState) { Set expandedElements = modelState.getExpandedElements(); if (action.getCollapseIds() != null) { @@ -74,8 +74,7 @@ private Optional handleCollapseExpandAction(final CollapseExpandAction a expansionListener.expansionChanged(action); } - return Optional.empty(); - + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ComputedBoundsActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ComputedBoundsActionHandler.java index 91bcf4f5..56ab4b2d 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ComputedBoundsActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ComputedBoundsActionHandler.java @@ -15,7 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.List; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.ComputedBoundsAction; @@ -35,7 +35,7 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof ComputedBoundsAction) { ComputedBoundsAction computedBoundsAction = (ComputedBoundsAction) action; @@ -47,7 +47,7 @@ public Optional execute(final Action action, final GraphicalModelState m } } } - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/DIActionProcessor.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/DIActionProcessor.java index 27a98e7c..6ca92fd6 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/DIActionProcessor.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/DIActionProcessor.java @@ -15,6 +15,8 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.Collections; +import java.util.List; import java.util.Optional; import org.eclipse.glsp.api.action.Action; @@ -36,12 +38,12 @@ public class DIActionProcessor implements ActionProcessor { protected ActionHandlerProvider handlerProvider; @Override - public Optional dispatch(final String clientId, final Action action) { + public List dispatch(final String clientId, final Action action) { Optional handler = handlerProvider.getHandler(action); if (handler.isPresent()) { return handler.get().execute(clientId, action); } - return Optional.empty(); + return Collections.emptyList(); } @Override diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ExecuteServerCommandActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ExecuteServerCommandActionHandler.java index f1afaed0..e0a7060b 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ExecuteServerCommandActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ExecuteServerCommandActionHandler.java @@ -15,6 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.List; import java.util.Optional; import org.eclipse.glsp.api.action.Action; @@ -35,7 +36,7 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof ExecuteServerCommandAction) { ExecuteServerCommandAction commandAction = (ExecuteServerCommandAction) action; Optional handler = commandHandlerProvider.getHandler(commandAction.getCommandId()); @@ -43,7 +44,7 @@ public Optional execute(final Action action, final GraphicalModelState m return handler.get().execute(commandAction.getCommandId(), commandAction.getOptions(), modelState); } } - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/LayoutActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/LayoutActionHandler.java index 61639165..0bbe9a75 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/LayoutActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/LayoutActionHandler.java @@ -15,7 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.List; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.LayoutAction; @@ -41,13 +41,13 @@ public boolean handles(final Action action) { } @Override - protected Optional execute(final Action action, final GraphicalModelState modelState) { + protected List execute(final Action action, final GraphicalModelState modelState) { if (serverConfiguration.getLayoutKind() == ServerLayoutKind.MANUAL) { if (layoutEngine != null) { layoutEngine.layout(modelState); } - return Optional.of(new RequestBoundsAction(modelState.getRoot())); + return listOf(new RequestBoundsAction(modelState.getRoot())); } - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ModelSubmissionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ModelSubmissionHandler.java index 90459998..f4627f2f 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ModelSubmissionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ModelSubmissionHandler.java @@ -15,7 +15,9 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.SetModelAction; @@ -38,7 +40,7 @@ public class ModelSubmissionHandler { private final Object modelLock = new Object(); private final int revision = 0; - public Optional doSubmitModel(final boolean update, final GraphicalModelState modelState) { + public List doSubmitModel(final boolean update, final GraphicalModelState modelState) { GModelRoot newRoot = modelState.getRoot(); if (serverConfiguration.getLayoutKind() == ServerLayoutKind.AUTOMATIC) { layoutEngine.layout(modelState); @@ -46,13 +48,12 @@ public Optional doSubmitModel(final boolean update, final GraphicalModel synchronized (modelLock) { if (newRoot.getRevision() == revision) { if (update) { - return Optional.of(new UpdateModelAction(newRoot, true)); - } else { - return Optional.of(new SetModelAction(newRoot)); + return Arrays.asList(new UpdateModelAction(newRoot, true)); } + return Arrays.asList(new SetModelAction(newRoot)); } } - return Optional.empty(); + return Collections.emptyList(); } public synchronized Object getModelLock() { return modelLock; } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OpenActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OpenActionHandler.java index 120b64d8..90077a20 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OpenActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OpenActionHandler.java @@ -15,7 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.List; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.OpenAction; @@ -34,13 +34,13 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof OpenAction) { if (modelElementOpenListener != null) { modelElementOpenListener.elementOpened((OpenAction) action); } } - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OperationActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OperationActionHandler.java index d6c4055c..37123642 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OperationActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/OperationActionHandler.java @@ -15,11 +15,12 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.List; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.AbstractOperationAction; import org.eclipse.glsp.api.action.kind.RequestBoundsAction; +import org.eclipse.glsp.api.action.kind.SetDirtyStateAction; import org.eclipse.glsp.api.handler.OperationHandler; import org.eclipse.glsp.api.model.GraphicalModelState; import org.eclipse.glsp.api.provider.OperationHandlerProvider; @@ -37,24 +38,24 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof AbstractOperationAction && operationHandlerProvider.isHandled((AbstractOperationAction) action)) { return doHandle((AbstractOperationAction) action, modelState); } - return Optional.empty(); + return none(); } - public Optional doHandle(final AbstractOperationAction action, final GraphicalModelState modelState) { + public List doHandle(final AbstractOperationAction action, final GraphicalModelState modelState) { if (operationHandlerProvider.isHandled(action)) { OperationHandler handler = operationHandlerProvider.getHandler(action).get(); String label = handler.getLabel(action); GModelRecordingCommand command = new GModelRecordingCommand(modelState.getRoot(), label, () -> handler.execute(action, modelState)); modelState.execute(command); - return Optional.of(new RequestBoundsAction(modelState.getRoot())); + return listOf(new RequestBoundsAction(modelState.getRoot()), new SetDirtyStateAction(modelState.isDirty())); } - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestContextActionsHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestContextActionsHandler.java index f88cb717..f732a77f 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestContextActionsHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestContextActionsHandler.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Optional; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.RequestContextActions; @@ -46,7 +45,7 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof RequestContextActions) { RequestContextActions requestContextAction = (RequestContextActions) action; List selectedElementIds = requestContextAction.getSelectedElementIds(); @@ -60,9 +59,9 @@ public Optional execute(final Action action, final GraphicalModelState m requestContextAction.getLastMousePosition(), args)); } - return Optional.of(new SetContextActions(items, requestContextAction.getArgs())); + return listOf(new SetContextActions(items, requestContextAction.getArgs())); } - return Optional.empty(); + return none(); } protected boolean equalsUiControl(final Map args, final String uiControlKey) { diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestMarkersHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestMarkersHandler.java index 3e0f742c..7fdc578b 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestMarkersHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestMarkersHandler.java @@ -37,7 +37,7 @@ public class RequestMarkersHandler extends AbstractActionHandler { protected ModelValidator validator; @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { RequestMarkersAction execAction = (RequestMarkersAction) action; List elementsIDs = execAction.getElementsIDs(); if (elementsIDs == null || elementsIDs.size() == 0) { // if no element ID is provided, compute the markers for @@ -55,7 +55,7 @@ public Optional execute(final Action action, final GraphicalModelState m } SetMarkersAction setMarkersAction = new SetMarkersAction(markers); - return Optional.of(setMarkersAction); + return listOf(setMarkersAction); } @Override diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestModelActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestModelActionHandler.java index 7d9423de..96eb7fbc 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestModelActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestModelActionHandler.java @@ -15,6 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.List; import java.util.Optional; import org.eclipse.glsp.api.action.Action; @@ -34,7 +35,7 @@ public class RequestModelActionHandler extends AbstractActionHandler { protected ModelFactory modelFactory; @Override - public Optional execute(final String clientId, final Action action) { + public List execute(final String clientId, final Action action) { this.clientId = clientId; Optional modelState = modelStateProvider.getModelState(clientId); if (modelState.isPresent()) { @@ -44,7 +45,7 @@ public Optional execute(final String clientId, final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof RequestModelAction) { RequestModelAction requestAction = (RequestModelAction) action; GModelRoot model = modelFactory.loadModel(requestAction, modelState); @@ -56,9 +57,9 @@ public Optional execute(final Action action, final GraphicalModelState m Action responseAction = needsClientLayout ? new RequestBoundsAction(modelState.getRoot()) : new SetModelAction(modelState.getRoot()); - return Optional.of(responseAction); + return listOf(responseAction); } - return Optional.empty(); + return none(); } @Override diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestOperationsActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestOperationsActionHandler.java index 4475d680..fa17ca4b 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestOperationsActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestOperationsActionHandler.java @@ -15,6 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.List; import java.util.Optional; import org.apache.log4j.Logger; @@ -39,31 +40,30 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof RequestOperationsAction) { RequestOperationsAction requestAction = (RequestOperationsAction) action; Optional diagramType = getDiagramType(requestAction, modelState); if (!diagramType.isPresent()) { LOG.info("RequestOperationsAction failed: No diagram type is present"); - return Optional.empty(); + return none(); } Optional configuration = diagramConfigurationProvider.get(diagramType.get()); if (!configuration.isPresent()) { LOG.info("RequestOperationsAction failed: No diagram confiuration found for : " + diagramType.get()); - return Optional.empty(); + return none(); } - return Optional.of(new SetOperationsAction(configuration.get().getOperations())); + return listOf(new SetOperationsAction(configuration.get().getOperations())); } - return Optional.empty(); + return none(); } private Optional getDiagramType(final RequestOperationsAction action, final GraphicalModelState modelState) { if (action.getDiagramType() != null && !action.getDiagramType().isEmpty()) { return Optional.of(action.getDiagramType()); - } else { - return ClientOptions.getValue(modelState.getClientOptions(), ClientOptions.DIAGRAM_TYPE); } + return ClientOptions.getValue(modelState.getClientOptions(), ClientOptions.DIAGRAM_TYPE); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestPopupModelActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestPopupModelActionHandler.java index 2c1e742f..fbfacb07 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestPopupModelActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestPopupModelActionHandler.java @@ -15,6 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.List; import java.util.Optional; import org.eclipse.glsp.api.action.Action; @@ -36,16 +37,16 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof RequestPopupModelAction && popupModelFactory != null) { RequestPopupModelAction requestAction = (RequestPopupModelAction) action; Optional element = modelState.getIndex().get(requestAction.getElementId()); if (popupModelFactory != null && element.isPresent()) { - return popupModelFactory.createPopupModel(element.get(), requestAction, modelState) - .map(popupModel -> new SetPopupModelAction(popupModel, requestAction.getBounds())); + return listOf(popupModelFactory.createPopupModel(element.get(), requestAction, modelState) + .map(popupModel -> new SetPopupModelAction(popupModel, requestAction.getBounds()))); } } - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestTypeHintsActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestTypeHintsActionHandler.java index 48525697..8fc74f9c 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestTypeHintsActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/RequestTypeHintsActionHandler.java @@ -15,6 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.List; import java.util.Optional; import org.apache.log4j.Logger; @@ -39,31 +40,30 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof RequestTypeHintsAction) { Optional diagramType = getDiagramType((RequestTypeHintsAction) action, modelState); if (!diagramType.isPresent()) { log.info("RequestTypeHintsAction failed: No diagram type is present"); - return Optional.empty(); + return none(); } Optional configuration = diagramConfigurationProvider.get(diagramType.get()); if (!configuration.isPresent()) { log.info("RequestTypeHintsAction failed: No diagram confiuration found for : " + diagramType.get()); - return Optional.empty(); + return none(); } - return Optional.of(new SetTypeHintsAction(configuration.get().getNodeTypeHints(), + return listOf(new SetTypeHintsAction(configuration.get().getNodeTypeHints(), configuration.get().getEdgeTypeHints())); } - return Optional.empty(); + return none(); } private Optional getDiagramType(final RequestTypeHintsAction action, final GraphicalModelState modelState) { if (action.getDiagramType() == null && !action.getDiagramType().isEmpty()) { return Optional.of(action.getDiagramType()); - } else { - return ClientOptions.getValue(modelState.getClientOptions(), ClientOptions.DIAGRAM_TYPE); } + return ClientOptions.getValue(modelState.getClientOptions(), ClientOptions.DIAGRAM_TYPE); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SaveModelActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SaveModelActionHandler.java index 0320be29..eb6d1fdd 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SaveModelActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SaveModelActionHandler.java @@ -21,11 +21,13 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.nio.charset.StandardCharsets; +import java.util.List; import java.util.Optional; import org.apache.log4j.Logger; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.SaveModelAction; +import org.eclipse.glsp.api.action.kind.SetDirtyStateAction; import org.eclipse.glsp.api.factory.GraphGsonConfiguratorFactory; import org.eclipse.glsp.api.model.GraphicalModelState; import org.eclipse.glsp.api.utils.ClientOptions; @@ -46,14 +48,11 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof SaveModelAction) { - SaveModelAction saveAction = (SaveModelAction) action; - if (saveAction != null) { - saveModelState(modelState); - } + saveModelState(modelState); } - return Optional.empty(); + return listOf(new SetDirtyStateAction(modelState.isDirty())); } private void saveModelState(final GraphicalModelState modelState) { @@ -61,6 +60,7 @@ private void saveModelState(final GraphicalModelState modelState) { try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) { Gson gson = gsonConfigurationFactory.configureGson().setPrettyPrinting().create(); gson.toJson(modelState.getRoot(), GGraph.class, writer); + modelState.saveIsDone(); } catch (IOException e) { LOG.error(e); } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SelectActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SelectActionHandler.java index 4361a091..87c4e7e8 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SelectActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/SelectActionHandler.java @@ -15,7 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.List; import java.util.Set; import org.eclipse.glsp.api.action.Action; @@ -36,19 +36,19 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { switch (action.getKind()) { case Action.Kind.SELECT: return handleSelectAction((SelectAction) action, modelState); case Action.Kind.SELECT_ALL: return handleSelectAllAction((SelectAllAction) action, modelState); default: - return Optional.empty(); + return none(); } } - private Optional handleSelectAllAction(final SelectAllAction action, final GraphicalModelState modelState) { + private List handleSelectAllAction(final SelectAllAction action, final GraphicalModelState modelState) { Set selectedElements = modelState.getSelectedElements(); if (action.isSelect()) { modelState.getIndex().allIds().forEach(id -> selectedElements.add(id)); @@ -58,10 +58,10 @@ private Optional handleSelectAllAction(final SelectAllAction action, fin if (modelSelectionListener != null) { modelSelectionListener.selectionChanged(action); } - return Optional.empty(); + return none(); } - private Optional handleSelectAction(final SelectAction action, final GraphicalModelState modelState) { + private List handleSelectAction(final SelectAction action, final GraphicalModelState modelState) { Set selectedElements = modelState.getSelectedElements(); if (action.getDeselectedElementsIDs() != null) { selectedElements.removeAll(action.getDeselectedElementsIDs()); @@ -72,7 +72,7 @@ private Optional handleSelectAction(final SelectAction action, final Gra if (modelSelectionListener != null) { modelSelectionListener.selectionChanged(action); } - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/UndoRedoActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/UndoRedoActionHandler.java index 81863010..9574a3b2 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/UndoRedoActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/UndoRedoActionHandler.java @@ -15,12 +15,13 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; -import java.util.Optional; +import java.util.List; import org.apache.log4j.Logger; import org.eclipse.glsp.api.action.Action; import org.eclipse.glsp.api.action.kind.RedoAction; import org.eclipse.glsp.api.action.kind.RequestBoundsAction; +import org.eclipse.glsp.api.action.kind.SetDirtyStateAction; import org.eclipse.glsp.api.action.kind.UndoAction; import org.eclipse.glsp.api.model.GraphicalModelState; @@ -33,16 +34,15 @@ public boolean handles(final Action action) { } @Override - public Optional execute(final Action action, final GraphicalModelState modelState) { + public List execute(final Action action, final GraphicalModelState modelState) { if (action instanceof UndoAction && modelState.canUndo()) { modelState.undo(); - return Optional.of(new RequestBoundsAction(modelState.getRoot())); + return listOf(new RequestBoundsAction(modelState.getRoot()), new SetDirtyStateAction(modelState.isDirty())); } else if (action instanceof RedoAction && modelState.canRedo()) { modelState.redo(); - return Optional.of(new RequestBoundsAction(modelState.getRoot())); + return listOf(new RequestBoundsAction(modelState.getRoot()), new SetDirtyStateAction(modelState.isDirty())); } - LOG.warn("Cannot undo or redo"); - return Optional.empty(); + return none(); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ValidateLabelEditActionHandler.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ValidateLabelEditActionHandler.java index 984431f2..455ecb0a 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ValidateLabelEditActionHandler.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/actionhandler/ValidateLabelEditActionHandler.java @@ -15,6 +15,7 @@ ********************************************************************************/ package org.eclipse.glsp.server.actionhandler; +import java.util.List; import java.util.Optional; import org.eclipse.glsp.api.action.Action; @@ -38,14 +39,14 @@ public boolean handles(final Action action) { } @Override - protected Optional execute(final Action action, final GraphicalModelState modelState) { + protected List execute(final Action action, final GraphicalModelState modelState) { ValidateLabelEditAction validateAction = (ValidateLabelEditAction) action; Optional element = modelState.getIndex().get(validateAction.getLabelId()); if (element.isPresent()) { - return Optional.of(new SetEditLabelValidationResultAction( + return listOf(new SetEditLabelValidationResultAction( editLabelValidator.validate(modelState, validateAction.getValue(), element.get()))); } - return Optional.of(new SetEditLabelValidationResultAction(EditLabelValidationResult.OK_RESULT)); + return listOf(new SetEditLabelValidationResultAction(EditLabelValidationResult.OK_RESULT)); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateImpl.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateImpl.java index 9984fdf2..3308e7b7 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateImpl.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateImpl.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Set; +import org.eclipse.emf.common.command.BasicCommandStack; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CommandStack; import org.eclipse.glsp.api.model.GraphicalModelState; @@ -31,7 +32,7 @@ public class ModelStateImpl implements GraphicalModelState { private Map options; private String clientId; private GModelRoot currentModel; - private CommandStack commandStack; + private BasicCommandStack commandStack; private Set expandedElements; private Set selectedElements; @@ -67,7 +68,7 @@ protected void initializeCommandStack() { public CommandStack getCommandStack() { return commandStack; } - protected void setCommandStack(final CommandStack commandStack) { + protected void setCommandStack(final BasicCommandStack commandStack) { if (this.commandStack != null) { this.commandStack.flush(); } @@ -136,4 +137,12 @@ public void redo() { commandStack.redo(); } + @Override + public boolean isDirty() { return commandStack.isSaveNeeded(); } + + @Override + public void saveIsDone() { + commandStack.saveIsDone(); + } + }