diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowGLSPModule.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowGLSPModule.java index 3bcbbbc3..23ea451f 100644 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowGLSPModule.java +++ b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/WorkflowGLSPModule.java @@ -28,7 +28,6 @@ import org.eclipse.glsp.example.workflow.labeledit.WorkflowLabelEditValidator; import org.eclipse.glsp.example.workflow.layout.WorkflowLayoutEngine; import org.eclipse.glsp.example.workflow.marker.WorkflowModelValidator; -import org.eclipse.glsp.example.workflow.model.WorkflowModelFactory; import org.eclipse.glsp.example.workflow.model.WorkflowNavigationTargetResolver; import org.eclipse.glsp.example.workflow.provider.NextNodeNavigationTargetProvider; import org.eclipse.glsp.example.workflow.provider.NodeDocumentationNavigationTargetProvider; @@ -47,7 +46,9 @@ import org.eclipse.glsp.server.features.contextactions.ContextActionsProvider; import org.eclipse.glsp.server.features.contextactions.RequestContextActionsHandler; import org.eclipse.glsp.server.features.contextmenu.ContextMenuItemProvider; -import org.eclipse.glsp.server.features.core.model.ModelFactory; +import org.eclipse.glsp.server.features.core.model.GModelFactory; +import org.eclipse.glsp.server.features.core.model.JsonFileGModelLoader; +import org.eclipse.glsp.server.features.core.model.ModelSourceLoader; import org.eclipse.glsp.server.features.directediting.ContextEditValidator; import org.eclipse.glsp.server.features.directediting.LabelEditValidator; import org.eclipse.glsp.server.features.modelsourcewatcher.FileWatcher; @@ -69,6 +70,26 @@ protected Class bindGLSPServer() { return WorkflowGLSPServer.class; } + @Override + protected Class bindSourceModelLoader() { + return JsonFileGModelLoader.class; + } + + @Override + protected Class bindGModelFactory() { + return GModelFactory.NullImpl.class; + } + + @Override + protected Class bindModelSourceWatcher() { + return FileWatcher.class; + } + + @Override + protected Class bindGraphExtension() { + return WFGraphExtension.class; + } + @Override protected void configureContextActionsProviders(final MultiBinding binding) { super.configureContextActionsProviders(binding); @@ -116,11 +137,6 @@ protected void configureActionHandlers(final MultiBinding binding binding.add(LogActionHandler.class); } - @Override - protected Class bindGraphExtension() { - return WFGraphExtension.class; - } - @Override public Class bindPopupModelFactory() { return WorkflowPopupFactory.class; @@ -156,13 +172,4 @@ protected Class bindNavigationTargetResolver return WorkflowNavigationTargetResolver.class; } - @Override - protected Class bindModelFactory() { - return WorkflowModelFactory.class; - } - - @Override - protected Class bindModelSourceWatcher() { - return FileWatcher.class; - } } diff --git a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/model/WorkflowModelFactory.java b/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/model/WorkflowModelFactory.java deleted file mode 100644 index 209694fd..00000000 --- a/examples/org.eclipse.glsp.example.workflow/src/org/eclipse/glsp/example/workflow/model/WorkflowModelFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************** - * 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.example.workflow.model; - -import org.eclipse.glsp.graph.GModelRoot; -import org.eclipse.glsp.server.actions.ActionDispatcher; -import org.eclipse.glsp.server.features.core.model.JsonFileModelFactory; -import org.eclipse.glsp.server.features.core.model.RequestModelAction; -import org.eclipse.glsp.server.model.GModelState; -import org.eclipse.glsp.server.utils.ServerMessageUtil; -import org.eclipse.glsp.server.utils.ServerStatusUtil; - -import com.google.inject.Inject; - -public class WorkflowModelFactory extends JsonFileModelFactory { - - @Inject - private ActionDispatcher actionDispatcher; - - @Override - public GModelRoot loadModel(final RequestModelAction action, final GModelState modelState) { - String clientId = modelState.getClientId(); - actionDispatcher.dispatch(clientId, ServerStatusUtil.info("Model loading in progress!")); - actionDispatcher.dispatch(clientId, ServerMessageUtil.info("Model loading in progress!")); - - GModelRoot modelRoot = super.loadModel(action, modelState); - - actionDispatcher.dispatch(clientId, ServerStatusUtil.clear()); - actionDispatcher.dispatch(clientId, ServerMessageUtil.clear()); - - return modelRoot; - } - -} diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/GLSPModule.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/GLSPModule.java index 3f9688f2..82c6c586 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/GLSPModule.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/di/GLSPModule.java @@ -25,7 +25,8 @@ import org.eclipse.glsp.server.features.commandpalette.CommandPaletteActionProvider; import org.eclipse.glsp.server.features.contextactions.ContextActionsProviderRegistry; import org.eclipse.glsp.server.features.contextmenu.ContextMenuItemProvider; -import org.eclipse.glsp.server.features.core.model.ModelFactory; +import org.eclipse.glsp.server.features.core.model.GModelFactory; +import org.eclipse.glsp.server.features.core.model.ModelSourceLoader; import org.eclipse.glsp.server.features.directediting.ContextEditValidatorRegistry; import org.eclipse.glsp.server.features.directediting.LabelEditValidator; import org.eclipse.glsp.server.features.modelsourcewatcher.ModelSourceWatcher; @@ -52,8 +53,10 @@ public abstract class GLSPModule extends AbstractModule { protected void configure() { // Configure default bindings bind(GLSPServer.class).to(bindGLSPServer()).in(Singleton.class); + bind(ModelSourceLoader.class).to(bindSourceModelLoader()); + bind(GModelFactory.class).to(bindGModelFactory()); + bind(ModelSourceWatcher.class).to(bindModelSourceWatcher()).in(Singleton.class); bind(PopupModelFactory.class).to(bindPopupModelFactory()); - bind(ModelFactory.class).to(bindModelFactory()); bind(ILayoutEngine.class).to(bindLayoutEngine()); bind(ModelValidator.class).to(bindModelValidator()); bind(ActionDispatcher.class).to(bindActionDispatcher()).in(Singleton.class); @@ -64,7 +67,6 @@ protected void configure() { bind(CommandPaletteActionProvider.class).to(bindCommandPaletteActionProvider()); bind(ContextMenuItemProvider.class).to(bindContextMenuItemProvider()); bind(NavigationTargetResolver.class).to(bindNavigationTargetResolver()); - bind(ModelSourceWatcher.class).to(bindModelSourceWatcher()).in(Singleton.class); bind(ClientSessionManager.class).toInstance(getClientSessionManager()); // Configure set suppliers bind(ActionRegistry.class).to(bindActionRegistry()).in(Singleton.class); @@ -88,7 +90,9 @@ protected void configure() { protected abstract Class bindGraphGsonConfiguratorFactory(); - protected abstract Class bindModelFactory(); + protected abstract Class bindSourceModelLoader(); + + protected abstract Class bindGModelFactory(); protected Class bindPopupModelFactory() { return PopupModelFactory.NullImpl.class; 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 d6f2ec53..a950bb53 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 @@ -36,7 +36,7 @@ public List executeAction(final ComputedBoundsAction action, final GMode GModelRoot model = modelState.getRoot(); if (model != null && model.getRevision() == action.getRevision()) { LayoutUtil.applyBounds(model, action, modelState); - return submissionHandler.submitModel(true, modelState, false); + return submissionHandler.submitModelDirectly(modelState); } } return none(); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/GModelFactory.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/GModelFactory.java new file mode 100644 index 00000000..f0af7dfc --- /dev/null +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/GModelFactory.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2019-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.features.core.model; + +import org.eclipse.glsp.graph.GModelIndex; +import org.eclipse.glsp.graph.GModelRoot; +import org.eclipse.glsp.server.actions.ActionHandler; +import org.eclipse.glsp.server.model.GModelState; +import org.eclipse.glsp.server.operations.OperationHandler; + +/** + * A graph model factory produces a graph model from the model state; typically its contained source model. + *

+ * The responsibility of a {@link GModelFactory} implementation is to define how a {@link GModelState} is to be + * translated into a {@link GModelRoot} that is sent to the client for rendering. Before a {@link GModelFactory} + * is invoked, the {@link ModelSourceLoader} has already been executed for loading the source model into the + * {@link GModelState}. The {@link GModelFactory} then produces the {@link GModelRoot} from the source model in the + * {@link GModelState}. Implementations of {@link GModelFactory} are usually specific to the type of source model, as + * they need to understand the source model in order to translate it into a graph model. + *

+ *

+ * The graph model factory is invoked after initial load of the source model and after each operation that is applied + * to the source model by an {@link OperationHandler} in order to update the graph model before sending it to the client + * for rendering. + *

+ *

+ * If an index is needed for mapping between the graph model and the source model, as is typically the case for + * {@link ActionHandler action handlers} and {@link OperationHandler operation handlers}, it is the responsibility of + * the graph model factory to create such an index while producing the graph model from the source model. The index + * shall be put into the model state too. Typically the {@link GModelIndex} is extended for a particular model source + * type as well. + *

+ * + * @see ModelSourceLoader + * @see GModelIndex + */ +public interface GModelFactory { + /** + * Create a {@link GModelRoot} from the specified modelState and puts it into the + * modelState. Optionally, this step also produces and sets a {@link GModelIndex} in the model state + * that allows mapping from graph model elements to source model elements and vice versa. + * + * @param modelState The model state into which the created graph model and index shall be put. + */ + void createGModel(GModelState modelState); + + /** + * Graph model factory to be used if the graph model is already available from the model source. + */ + final class NullImpl implements GModelFactory { + @Override + public void createGModel(final GModelState modelState) { + // noop + } + } +} diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileModelFactory.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileGModelLoader.java similarity index 67% rename from plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileModelFactory.java rename to plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileGModelLoader.java index fbc5129e..7ef8793a 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileModelFactory.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/JsonFileGModelLoader.java @@ -24,7 +24,6 @@ import java.util.Optional; import org.eclipse.glsp.graph.GGraph; -import org.eclipse.glsp.graph.GModelRoot; import org.eclipse.glsp.server.jsonrpc.GraphGsonConfiguratorFactory; import org.eclipse.glsp.server.model.GModelState; import org.eclipse.glsp.server.protocol.GLSPServerException; @@ -34,29 +33,23 @@ import com.google.inject.Inject; /** - * A base class which can be used for all model factories that load an SModel - * from a json file. - * + * A source model loader that reads the graph model directly from a JSON file. */ -public class JsonFileModelFactory implements ModelFactory { +public class JsonFileGModelLoader implements ModelSourceLoader { @Inject private GraphGsonConfiguratorFactory gsonConfigurationFactory; - private GModelRoot modelRoot; - @Override - public GModelRoot loadModel(final RequestModelAction action, final GModelState modelState) { + public void loadSourceModel(final RequestModelAction action, final GModelState modelState) { final Optional file = ClientOptions.getSourceUriAsFile(action.getOptions()); - if (file.isPresent() && file.get().exists()) { - try (Reader reader = new InputStreamReader(new FileInputStream(file.get()), StandardCharsets.UTF_8)) { - Gson gson = gsonConfigurationFactory.configureGson().create(); - modelRoot = gson.fromJson(reader, GGraph.class); - } catch (IOException e) { - throw new GLSPServerException("Could not load model from file: " + file.get().toURI().toString(), e); - } + try (Reader reader = new InputStreamReader(new FileInputStream(file.get()), StandardCharsets.UTF_8)) { + Gson gson = gsonConfigurationFactory.configureGson().create(); + modelState.setRoot(gson.fromJson(reader, GGraph.class)); + modelState.getRoot().setRevision(-1); + } catch (IOException e) { + throw new GLSPServerException("Could not load model from file: " + file.get().toURI().toString(), e); } - return modelRoot; } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelFactory.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelFactory.java deleted file mode 100644 index 40862ed2..00000000 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019 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.features.core.model; - -import org.eclipse.glsp.graph.GModelRoot; -import org.eclipse.glsp.server.model.GModelState; - -public interface ModelFactory { - - GModelRoot loadModel(RequestModelAction action, GModelState modelState); - - final class NullImpl implements ModelFactory { - - @Override - public GModelRoot loadModel(final RequestModelAction action, final GModelState modelState) { - return null; - } - - } - -} 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 new file mode 100644 index 00000000..94243452 --- /dev/null +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/ModelSourceLoader.java @@ -0,0 +1,43 @@ +/******************************************************************************** + * 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.features.core.model; + +import org.eclipse.glsp.server.model.GModelState; +import org.eclipse.glsp.server.utils.ClientOptions; + +/** + * A source model loader loads models into the model state. + *

+ * A source model is an arbitrary model from which the graph model of the diagram is to be created. + * Implementations of source model loaders are specific to the type of source model or persistence format that is used + * for a type of source model. A source model loader obtains the information on which source model shall loaded from a + * {@link RequestModelAction}; typically its client options. Once the source model is loaded, a model loader is expected + * to put the loaded source model into the model state for further processing, such as transforming the loaded model + * into a graph model (see {@link GModelFactory}). + *

+ * + * @see ClientOptions + * @see GModelFactory + */ +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. + */ + void loadSourceModel(RequestModelAction action, GModelState modelState); +} 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 54326140..9ac61d33 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 @@ -16,7 +16,6 @@ package org.eclipse.glsp.server.features.core.model; import java.util.Arrays; -import java.util.Collections; import java.util.List; import org.eclipse.glsp.graph.GModelRoot; @@ -42,74 +41,60 @@ public class ModelSubmissionHandler { @Inject protected DiagramConfigurationRegistry diagramConfigurationRegistry; + @Inject + protected GModelFactory modelFactory; + private final Object modelLock = new Object(); - private final int revision = 0; /** + * Returns a list of actions to update the client-side model, based on the specified modelState. *

- * Compute and return a list of actions to update the client-side model, based on the specified modelState. - * 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 + * 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. *

- *

- * Equivalent to doSubmitModel(update, modelState, true). - *

* - * @param update - * true if this is an update to an existing model; false - * if this is a new model (e.g. after loading a model) - * @param modelState - * The {@link GModelState} - * @return - * A list of Actions to be processed in order to submit the model + * @param modelState The model state to submit. + * @return A list of actions to be processed in order to submit the model. */ - public List submitModel(final boolean update, final GModelState modelState) { - return submitModel(update, modelState, true); + public List submitModel(final GModelState modelState) { + modelFactory.createGModel(modelState); + modelState.getRoot().setRevision(modelState.getRoot().getRevision() + 1); + DiagramConfiguration diagramConfiguration = diagramConfigurationRegistry.get(modelState); + if (diagramConfiguration.getLayoutKind() == ServerLayoutKind.AUTOMATIC) { + layoutEngine.layout(modelState); + } + if (diagramConfiguration.needsClientLayout()) { + synchronized (modelLock) { + return Arrays.asList(new RequestBoundsAction(modelState.getRoot()), + new SetDirtyStateAction(modelState.isDirty())); + } + } + return submitModelDirectly(modelState); } /** + * Returns a list of actions to directly update the client-side model without any server- or client-side layouting. *

- * Compute and return a list of actions to update the client-side model, based on the specified modelState. - * 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 + * Typically {@link ActionHandler action handlers} don't invoke this method but use {@link #submitModel(GModelState)} + * 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. *

* - * @param update - * true if this is an update to an existing model; false - * if this is a new model (e.g. after loading a model) - * @param modelState - * The {@link GModelState} - * @param layout - * Whether layout should be processed. This should be true for most actions; - * false for actions that already react to client-layout changes - * (i.e. {@link ComputedBoundsAction} ). - * @return - * A list of Actions to be processed in order to submit the model. + * @param modelState The model state to submit. + * @return A list of actions to be processed in order to submit the model. */ - public List submitModel(final boolean update, final GModelState modelState, final boolean layout) { - GModelRoot newRoot = modelState.getRoot(); - DiagramConfiguration diagramConfiguration = diagramConfigurationRegistry.get(modelState); - if (diagramConfiguration.getLayoutKind() == ServerLayoutKind.AUTOMATIC) { - layoutEngine.layout(modelState); - } - - boolean needsClientLayout = layout && diagramConfiguration.needsClientLayout(); - + public List submitModelDirectly(final GModelState modelState) { + GModelRoot gModel = modelState.getRoot(); + Action action = gModel.getRevision() == 0 ? new SetModelAction(gModel) : new UpdateModelAction(gModel); synchronized (modelLock) { - if (newRoot.getRevision() == revision) { - if (update) { - Action updateModel = needsClientLayout ? new RequestBoundsAction(modelState.getRoot()) - : new UpdateModelAction(newRoot, true); - return Arrays.asList(updateModel, new SetDirtyStateAction(modelState.isDirty())); - } - Action setModel = needsClientLayout ? new RequestBoundsAction(modelState.getRoot()) - : new SetModelAction(newRoot); - return Arrays.asList(setModel); - } + return Arrays.asList(action, new SetDirtyStateAction(modelState.isDirty())); } - return Collections.emptyList(); } 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 f746ab8f..8a773a33 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 @@ -17,21 +17,26 @@ import java.util.List; -import org.eclipse.glsp.graph.GModelRoot; 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; +import org.eclipse.glsp.server.utils.ServerStatusUtil; import com.google.inject.Inject; public class RequestModelActionHandler extends BasicActionHandler { @Inject - protected ModelFactory modelFactory; + protected ModelSourceLoader sourceModelLoader; @Inject - private ModelSourceWatcher modelSourceWatcher; + protected ActionDispatcher actionDispatcher; + + @Inject + protected ModelSourceWatcher modelSourceWatcher; @Inject protected ModelSubmissionHandler modelSubmissionHandler; @@ -39,10 +44,24 @@ public class RequestModelActionHandler extends BasicActionHandler executeAction(final RequestModelAction action, final GModelState modelState) { modelState.setClientOptions(action.getOptions()); - GModelRoot model = modelFactory.loadModel(action, modelState); - modelState.setRoot(model); + + notifyStartLoading(modelState); + sourceModelLoader.loadSourceModel(action, modelState); + notifyFinishedLoading(modelState); + modelSourceWatcher.startWatching(modelState); - return modelSubmissionHandler.submitModel(false, modelState); + + return modelSubmissionHandler.submitModel(modelState); + } + + protected void notifyStartLoading(final GModelState modelState) { + actionDispatcher.dispatch(modelState.getClientId(), ServerStatusUtil.info("Model loading in progress!")); + actionDispatcher.dispatch(modelState.getClientId(), ServerMessageUtil.info("Model loading in progress!")); + } + + protected void notifyFinishedLoading(final GModelState modelState) { + actionDispatcher.dispatch(modelState.getClientId(), ServerStatusUtil.clear()); + actionDispatcher.dispatch(modelState.getClientId(), ServerMessageUtil.clear()); } } diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/UpdateModelAction.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/UpdateModelAction.java index 822ac218..28f7df12 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/UpdateModelAction.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/features/core/model/UpdateModelAction.java @@ -29,6 +29,10 @@ public UpdateModelAction() { super(ID); } + public UpdateModelAction(final GModelRoot newRoot) { + this(newRoot, true); + } + public UpdateModelAction(final GModelRoot newRoot, final boolean animate) { this(); this.newRoot = newRoot; 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 f37a7a55..b247979d 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 @@ -36,10 +36,10 @@ public class UndoRedoActionHandler implements ActionHandler { public List execute(final Action action, final GModelState modelState) { if (action instanceof UndoAction && modelState.canUndo()) { modelState.undo(); - return modelSubmissionHandler.submitModel(true, modelState); + return modelSubmissionHandler.submitModel(modelState); } else if (action instanceof RedoAction && modelState.canRedo()) { modelState.redo(); - return modelSubmissionHandler.submitModel(true, modelState); + return modelSubmissionHandler.submitModel(modelState); } LOG.warn("Cannot undo or redo"); return none(); diff --git a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateProvider.java b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateProvider.java index 5d62b420..1d279693 100644 --- a/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateProvider.java +++ b/plugins/org.eclipse.glsp.server/src/org/eclipse/glsp/server/model/ModelStateProvider.java @@ -19,8 +19,7 @@ public interface ModelStateProvider { /** - * Returns the model state for a given clientId. Note that each sprotty diagram - * is counted as an individual client. + * Returns the model state for a given clientId. Note that each diagram is counted as an individual client. * * @param clientId clientId/widgetId * @return the corresponding model state 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 11ae551f..6c2669de 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 @@ -57,7 +57,7 @@ protected List executeHandler(final Operation operation, final Operation GModelRecordingCommand command = new GModelRecordingCommand(modelState.getRoot(), handler.getLabel(), () -> handler.execute(operation, modelState)); modelState.execute(command); - return modelSubmissionHandler.submitModel(true, modelState); + return modelSubmissionHandler.submitModel(modelState); } public static Optional getOperationHandler(final Operation operation,