From 4d5824189afc714931fc64d9392647226e295a98 Mon Sep 17 00:00:00 2001 From: vhemery Date: Wed, 17 Feb 2021 17:17:43 +0100 Subject: [PATCH] Absolute full path as modelURI causes error #72 (#80) Fixing absolute file URI with device for windows. Moving the adaptModelUri method to ModelResourceManager. Signed-off-by: vhemery --- .../common/DefaultModelResourceManager.java | 25 +++++++++ .../emf/common/ModelResourceManager.java | 15 ++++++ .../emf/common/ModelServerRouting.java | 54 ++++++------------- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelResourceManager.java b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelResourceManager.java index 63c2c80c..f250595c 100644 --- a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelResourceManager.java +++ b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelResourceManager.java @@ -39,6 +39,7 @@ import org.eclipse.emfcloud.modelserver.emf.configuration.ServerConfiguration; import org.emfjson.jackson.resource.JsonResourceFactory; +import com.google.common.base.Strings; import com.google.common.collect.Maps; import com.google.inject.Inject; @@ -332,4 +333,28 @@ public boolean getDirtyState(final String modeluri) { return getEditingDomain(getResourceSet(modeluri)).isDirty(); } + /** + * Adapt the model URI specified by the client to an absolute file + * scheme URI. + * + * @param modelUri the client-supplied model URI + * @return the absolute file URI + */ + @Override + public String adaptModelUri(final String modelUri) { + URI uri = URI.createURI(modelUri, true); + if (uri.isRelative()) { + if (serverConfiguration.getWorkspaceRootURI().isFile()) { + return uri.resolve(serverConfiguration.getWorkspaceRootURI()).toString(); + } + return URI.createFileURI(modelUri).toString(); + } + // Create file URI from path if modelUri is already absolute path (file:/ or full path file:///) + // to ensure consistent usage of org.eclipse.emf.common.util.URI + if (uri.hasDevice() && !Strings.isNullOrEmpty(uri.device())) { + return URI.createFileURI(uri.device() + uri.path()).toString(); + } + return URI.createFileURI(uri.path()).toString(); + } + } diff --git a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelResourceManager.java b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelResourceManager.java index 6d2290b1..7d83c8bc 100644 --- a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelResourceManager.java +++ b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelResourceManager.java @@ -62,4 +62,19 @@ public interface ModelResourceManager { boolean getDirtyState(String modeluri); + /** + * Adapt the model URI specified by the client. + * + * Subclasses may override for taking in account the server configuration and specific URI schemes. + * + * @param modelUri the client-supplied model URI + * @return the adapted URI ready to be consumed + */ + default String adaptModelUri(final String modelUri) { + URI uri = URI.createURI(modelUri, true); + // we do not know the server configuration for relative URIs nor the possible schemes here... + // concrete implementations would probably override + return uri.toString(); + } + } diff --git a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelServerRouting.java b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelServerRouting.java index 91225746..ae50ac59 100644 --- a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelServerRouting.java +++ b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/ModelServerRouting.java @@ -26,11 +26,9 @@ import java.util.concurrent.CompletableFuture; import org.apache.log4j.Logger; -import org.eclipse.emf.common.util.URI; import org.eclipse.emfcloud.modelserver.common.ModelServerPathParameters; import org.eclipse.emfcloud.modelserver.common.ModelServerPaths; import org.eclipse.emfcloud.modelserver.common.Routing; -import org.eclipse.emfcloud.modelserver.emf.configuration.ServerConfiguration; import com.google.inject.Inject; @@ -43,15 +41,15 @@ public class ModelServerRouting extends Routing { private static final Logger LOG = Logger.getLogger(ModelServerRouting.class.getSimpleName()); private final Javalin javalin; - private final ServerConfiguration serverConfiguration; + private final ModelResourceManager resourceManager; // Do not process certain requests while server is being configured. protected CompletableFuture onServerConfigured; @Inject - public ModelServerRouting(final Javalin javalin, final ServerConfiguration serverConfiguration) { + public ModelServerRouting(final Javalin javalin, final ModelResourceManager resourceManager) { this.javalin = javalin; - this.serverConfiguration = serverConfiguration; + this.resourceManager = resourceManager; this.onServerConfigured = CompletableFuture.completedFuture(null); } @@ -74,7 +72,7 @@ public void bindRoutes() { // CREATE post(ModelServerPaths.MODEL_BASE_PATH, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).create(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -83,7 +81,7 @@ public void bindRoutes() { // GET ONE MODEL/GET ALL MODELS get(ModelServerPaths.MODEL_BASE_PATH, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).getOne(ctx, param), () -> getController(ModelController.class).getAll(ctx)); @@ -92,7 +90,7 @@ public void bindRoutes() { // GET MODEL ELEMENT get(ModelServerPaths.MODEL_ELEMENT, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( modelUriParam -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.ELEMENT_ID).ifPresentOrElse( @@ -111,7 +109,7 @@ public void bindRoutes() { // UPDATE patch(ModelServerPaths.MODEL_BASE_PATH, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).update(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -120,7 +118,7 @@ public void bindRoutes() { // DELETE delete(ModelServerPaths.MODEL_BASE_PATH, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).delete(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -129,7 +127,7 @@ public void bindRoutes() { // EDIT - execute commands patch(ModelServerPaths.EDIT, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).executeCommand(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -138,7 +136,7 @@ public void bindRoutes() { // SAVE get(ModelServerPaths.SAVE, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).save(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -150,7 +148,7 @@ public void bindRoutes() { // UNDO get(ModelServerPaths.UNDO, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).undo(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -159,7 +157,7 @@ public void bindRoutes() { // REDO get(ModelServerPaths.REDO, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).redo(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -168,7 +166,7 @@ public void bindRoutes() { // VALIDATE get(ModelServerPaths.VALIDATION, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).validate(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -177,7 +175,7 @@ public void bindRoutes() { // GET CONSTRAINTS get(ModelServerPaths.VALIDATION_CONSTRAINTS, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(ModelController.class).getValidationConstraints(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -189,7 +187,7 @@ public void bindRoutes() { // GET JSON TYPE SCHEMA get(ModelServerPaths.TYPE_SCHEMA, ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( param -> getController(SchemaController.class).getTypeSchema(ctx, param), () -> handleHttpError(ctx, 400, "Missing parameter 'modeluri'!")); @@ -225,7 +223,7 @@ public void bindRoutes() { ws(ModelServerPaths.SUBSCRIPTION, wsHandler -> { wsHandler.onConnect(ctx -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.MODEL_URI) - .map(this::adaptModelUri) + .map(resourceManager::adaptModelUri) .ifPresentOrElse( modeluri -> { getQueryParam(ctx.queryParamMap(), ModelServerPathParameters.TIMEOUT) @@ -303,26 +301,6 @@ private Optional getQueryParam(final Map> queryPara return Optional.empty(); } - /** - * Adapt the model URI specified by the client to an absolute file - * scheme URI. - * - * @param modelUri the client-supplied model URI - * @return the absolute file URI - */ - private String adaptModelUri(final String modelUri) { - URI uri = URI.createURI(modelUri, true); - if (uri.isRelative()) { - if (serverConfiguration.getWorkspaceRootURI().isFile()) { - return uri.resolve(serverConfiguration.getWorkspaceRootURI()).toString(); - } - return URI.createFileURI(modelUri).toString(); - } - // Create file URI from path if modelUri is already absolute path (file:/ or full path file:///) - // to ensure consistent usage of org.eclipse.emf.common.util.URI - return URI.createFileURI(uri.path()).toString(); - } - private void handleHttpError(final Context ctx, final int statusCode, final String errorMsg) { LOG.error(errorMsg); ctx.status(statusCode).json(JsonResponse.error(errorMsg));