Skip to content

Commit

Permalink
Centralize model loading and GModel creation (#96)
Browse files Browse the repository at this point in the history
* Centralize model loading and GModel creation

Fixes eclipse-glsp/glsp#119

* Update copyright

* Make fields protected
  • Loading branch information
planger authored Jan 4, 2021
1 parent 2a60e9b commit 88dda7d
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -69,6 +70,26 @@ protected Class<? extends GLSPServer> bindGLSPServer() {
return WorkflowGLSPServer.class;
}

@Override
protected Class<? extends ModelSourceLoader> bindSourceModelLoader() {
return JsonFileGModelLoader.class;
}

@Override
protected Class<? extends GModelFactory> bindGModelFactory() {
return GModelFactory.NullImpl.class;
}

@Override
protected Class<? extends ModelSourceWatcher> bindModelSourceWatcher() {
return FileWatcher.class;
}

@Override
protected Class<? extends GraphExtension> bindGraphExtension() {
return WFGraphExtension.class;
}

@Override
protected void configureContextActionsProviders(final MultiBinding<ContextActionsProvider> binding) {
super.configureContextActionsProviders(binding);
Expand Down Expand Up @@ -116,11 +137,6 @@ protected void configureActionHandlers(final MultiBinding<ActionHandler> binding
binding.add(LogActionHandler.class);
}

@Override
protected Class<? extends GraphExtension> bindGraphExtension() {
return WFGraphExtension.class;
}

@Override
public Class<? extends PopupModelFactory> bindPopupModelFactory() {
return WorkflowPopupFactory.class;
Expand Down Expand Up @@ -156,13 +172,4 @@ protected Class<? extends NavigationTargetResolver> bindNavigationTargetResolver
return WorkflowNavigationTargetResolver.class;
}

@Override
protected Class<? extends ModelFactory> bindModelFactory() {
return WorkflowModelFactory.class;
}

@Override
protected Class<? extends ModelSourceWatcher> bindModelSourceWatcher() {
return FileWatcher.class;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -88,7 +90,9 @@ protected void configure() {

protected abstract Class<? extends GraphGsonConfiguratorFactory> bindGraphGsonConfiguratorFactory();

protected abstract Class<? extends ModelFactory> bindModelFactory();
protected abstract Class<? extends ModelSourceLoader> bindSourceModelLoader();

protected abstract Class<? extends GModelFactory> bindGModelFactory();

protected Class<? extends PopupModelFactory> bindPopupModelFactory() {
return PopupModelFactory.NullImpl.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public List<Action> 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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
* <p>
* 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.
* </p>
* <p>
* 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.
* </p>
* <p>
* 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.
* </p>
*
* @see ModelSourceLoader
* @see GModelIndex
*/
public interface GModelFactory {
/**
* Create a {@link GModelRoot} from the specified <code>modelState</code> and puts it into the
* <code>modelState</code>. 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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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> 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;
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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.
* <p>
* A <i>source model</i> 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}).
* </p>
*
* @see ClientOptions
* @see GModelFactory
*/
public interface ModelSourceLoader {
/**
* Loads a source model into the <code>modelState</code>.
*
* @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);
}
Loading

0 comments on commit 88dda7d

Please sign in to comment.