diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..27014d3f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,48 @@ +name: Build + +on: [pull_request] + +jobs: + build-m2: + strategy: + # do not cancel other builds if one fails + fail-fast: false + matrix: + os: [windows-2019, ubuntu-18.04, macos-10.15] + + runs-on: ${{ matrix.os }} + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Build with Maven + run: mvn -B -Pm2 clean verify --file pom.xml + + build-p2: + strategy: + # do not cancel other builds if one fails + fail-fast: false + matrix: + os: [windows-2019, ubuntu-18.04, macos-10.15] + + runs-on: ${{ matrix.os }} + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Build with Maven + run: mvn -B -Pp2 clean verify --file pom.xml diff --git a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultUriHelper.java b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultUriHelper.java index dc0803b7..f67c9612 100644 --- a/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultUriHelper.java +++ b/bundles/org.eclipse.emfcloud.modelserver.emf/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultUriHelper.java @@ -67,15 +67,8 @@ public URI withTrailingSeparator(final URI uri) { @Override public Optional toFileUri(final String fileUrl) { try { - String decodedUrl = URLDecoder.decode(fileUrl, "UTF-8"); - URI uri = URI.createURI(decodedUrl, true); - if (uri.scheme() == null) { - uri = withTrailingSeparator(URI.createFileURI(decodedUrl)); - } - if (uri.isRelative()) { - URI cwd = URI.createFileURI(System.getProperty("user.dir")); - uri = uri.resolve(withTrailingSeparator(cwd)); - } + File file = getAbsoluteFile(fileUrl); + URI uri = withTrailingSeparator(URI.createFileURI(file.toURI().normalize().getPath())); return Optional.ofNullable(uri).filter(URI::isFile); } catch (NullPointerException | IllegalArgumentException | UnsupportedEncodingException e) { LOG.warn(String.format("Could not convert to filePath! ā€™%sā€™ is not a valid URL", fileUrl)); @@ -83,6 +76,15 @@ public Optional toFileUri(final String fileUrl) { } } + protected File getAbsoluteFile(final String fileUrl) throws UnsupportedEncodingException { + String decodedUrl = URLDecoder.decode(withoutFileScheme(fileUrl), "UTF-8"); + File file = new File(decodedUrl); + if (!file.isAbsolute()) { + file = new File(System.getProperty("user.dir"), decodedUrl); + } + return file; + } + @Override public Optional toDirectoryUri(final String uri) { return toFileUri(uri).map(this::withTrailingSeparator); @@ -105,4 +107,8 @@ public static URI withEmptyAuthority(final URI uri) { : uri; } + public static String withoutFileScheme(final String uri) { + return uri.startsWith("file:/") ? uri.substring(6) : uri; + } + } diff --git a/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/EMFJsonConverterTest.java b/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/EMFJsonConverterTest.java index fb8a0894..a014f74c 100644 --- a/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/EMFJsonConverterTest.java +++ b/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/EMFJsonConverterTest.java @@ -10,6 +10,7 @@ ********************************************************************************/ package org.eclipse.emfcloud.modelserver.emf; +import static org.eclipse.emfcloud.modelserver.tests.util.OSUtil.osLineSeparator; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -28,12 +29,11 @@ import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emfcloud.modelserver.common.codecs.EMFJsonConverter; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.eclipse.emfcloud.modelserver.common.codecs.EMFJsonConverter; - public class EMFJsonConverterTest extends AbstractResourceTest { private EMFJsonConverter emfJsonConverter; @@ -51,8 +51,10 @@ public static void beforeClass() { @Before public void before() throws IOException { this.emfJsonConverter = new EMFJsonConverter(); - simpleTestJson = "{\n" + " \"eClass\" : \"http://www.eclipse.org/emf/2002/Ecore#//EClass\",\n" - + " \"name\" : \"SimpleTest\"\n" + "}"; + simpleTestJson = osLineSeparator("{\n" + + " \"eClass\" : \"http://www.eclipse.org/emf/2002/Ecore#//EClass\",\n" + + " \"name\" : \"SimpleTest\"\n" + + "}"); simpleTestEClass = EcoreFactory.eINSTANCE.createEClass(); simpleTestEClass.setName("SimpleTest"); diff --git a/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelControllerTest.java b/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelControllerTest.java index bb4538f2..ed858b5d 100644 --- a/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelControllerTest.java +++ b/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/common/DefaultModelControllerTest.java @@ -12,6 +12,7 @@ import static org.eclipse.emfcloud.modelserver.jsonschema.Json.prop; import static org.eclipse.emfcloud.modelserver.tests.util.EMFMatchers.eEqualTo; +import static org.eclipse.emfcloud.modelserver.tests.util.OSUtil.osLineSeparator; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -106,7 +107,7 @@ public void before() throws NoSuchFieldException, SecurityException { URI uri = URI.createFileURI("resources/Test1.ecore"); Optional resource = Optional.of(set.getResource(uri, true)); - when(serverConfiguration.getWorkspaceRootURI()).thenReturn(URI.createFileURI("/home/modelserver/workspace/")); + when(serverConfiguration.getWorkspaceRootURI()).thenReturn(URI.createFileURI(System.getProperty("user.home"))); codecs = new DICodecsManager(Map.of(ModelServerPathParametersV1.FORMAT_XMI, new XmiCodec())); when(modelRepository.getModel(getModelUri("Test1.ecore").toString())) .thenReturn(Optional.of(resource.get().getContents().get(0))); @@ -195,8 +196,7 @@ public void updateXmi() throws EncodingException { public void executeCommand() throws EncodingException, DecodingException { ResourceSet rset = new ResourceSetImpl(); String modeluri = "SuperBrewer3000.json"; - JsonResource res = new JsonResource( - URI.createURI(modeluri).resolve(serverConfiguration.getWorkspaceRootURI())); + JsonResource res = createJsonResource(modeluri); rset.getResources().add(res); final EClass task = EcoreFactory.eINSTANCE.createEClass(); res.getContents().add(task); @@ -236,8 +236,7 @@ public void executeCommand() throws EncodingException, DecodingException { public void addCommandNotification() throws EncodingException, DecodingException { ResourceSet rset = new ResourceSetImpl(); String modeluri = "SuperBrewer3000.json"; - JsonResource res = new JsonResource( - URI.createURI(modeluri).resolve(serverConfiguration.getWorkspaceRootURI())); + JsonResource res = createJsonResource(modeluri); rset.getResources().add(res); final EClass eClass = EcoreFactory.eINSTANCE.createEClass(); res.getContents().add(eClass); @@ -307,7 +306,8 @@ public void getModelelementByIdXmiFormat() throws EncodingException { modelController.getModelElementById(context, "test", "//@workflows.0"); - String expectedXmiSnippet = "\n\n"; + String expectedXmiSnippet = osLineSeparator( + "\n\n"); JsonNode expectedResponse = Json.object( prop(JsonResponseMember.TYPE, Json.text(JsonResponseType.SUCCESS)), prop(JsonResponseMember.DATA, Json.text(expectedXmiSnippet))); @@ -344,7 +344,8 @@ public void getModelelementByNameXmiFormat() throws EncodingException { modelController.getModelElementById(context, "test", "PreHeat"); - String expectedXmiSnippet = "\n\n"; + String expectedXmiSnippet = osLineSeparator( + "\n\n"); JsonNode expectedResponse = Json.object( prop(JsonResponseMember.TYPE, Json.text(JsonResponseType.SUCCESS)), prop(JsonResponseMember.DATA, Json.text(expectedXmiSnippet))); @@ -410,4 +411,9 @@ protected boolean matchesSafely(final String item) { }; } + private JsonResource createJsonResource(final String modeluri) { + return new JsonResource( + URI.createHierarchicalURI(new String[] { modeluri }, null, null) + .resolve(serverConfiguration.getWorkspaceRootURI())); + } } diff --git a/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/configuration/DefaultServerConfigurationTest.java b/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/configuration/DefaultServerConfigurationTest.java index 6babe4b8..9fd2e78a 100644 --- a/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/configuration/DefaultServerConfigurationTest.java +++ b/tests/org.eclipse.emfcloud.modelserver.emf.tests/src/org/eclipse/emfcloud/modelserver/emf/configuration/DefaultServerConfigurationTest.java @@ -10,7 +10,8 @@ ********************************************************************************/ package org.eclipse.emfcloud.modelserver.emf.configuration; -import static org.hamcrest.CoreMatchers.endsWith; +import static org.eclipse.emfcloud.modelserver.tests.util.OSUtil.osEndsWith; +import static org.eclipse.emfcloud.modelserver.tests.util.OSUtil.osIs; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -31,19 +32,19 @@ public class DefaultServerConfigurationTest { @Test public void normalizeWorkspaceRoot() { serverConfiguration.setWorkspaceRoot("foo"); - assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), endsWith("foo/")); + assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), osEndsWith("foo" + File.separator)); } @Test public void normalizeWorkspaceRootEncoded() throws UnsupportedEncodingException { serverConfiguration.setWorkspaceRoot("file:/c%3A/foo%20bar/"); - assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), endsWith("c:/foo bar/")); + assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), osEndsWith("c:/foo bar/")); } @Test public void normalizeWorkspaceRootSlashAlreadyPresent() { serverConfiguration.setWorkspaceRoot("foo/"); - assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), endsWith("foo/")); + assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), osEndsWith("foo/")); } @Test @@ -61,7 +62,8 @@ public void setWorkspaceRoot() { serverConfiguration.setWorkspaceRoot("."); URI expected = URI.createFileURI(cwd.getAbsolutePath()).appendSegment(""); // trailing slash assertThat(serverConfiguration.getWorkspaceRootURI(), is(expected)); - assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), is(cwd.getAbsolutePath() + "/")); + assertThat(serverConfiguration.getWorkspaceRootURI().toFileString(), + is(cwd.getAbsolutePath() + File.separator)); } @Test @@ -72,7 +74,7 @@ public void getUiSchemaFolder() { URI expected = URI.createFileURI(cwd.getAbsolutePath() + "/ui-schema-folder").appendSegment(""); // trailing slash assertThat(serverConfiguration.getUiSchemaFolderURI(), is(expected)); assertThat(serverConfiguration.getUiSchemaFolderURI().toFileString(), - is(cwd.getAbsolutePath() + "/ui-schema-folder/")); + osIs(cwd.getAbsolutePath() + "/ui-schema-folder/")); } @Test @@ -80,15 +82,15 @@ public void isUiSchemaFolder() { File cwd = getCWD(); serverConfiguration.setUiSchemaFolder("./ui-schema-folder"); - String expected = cwd.getAbsolutePath() + "/ui-schema-folder"; + String expected = cwd.getAbsolutePath() + File.separator + "ui-schema-folder"; // true with or without trailing slash assertThat(serverConfiguration.isUiSchemaFolder(expected), is(true)); - assertThat(serverConfiguration.isUiSchemaFolder(expected + "/"), is(true)); + assertThat(serverConfiguration.isUiSchemaFolder(expected + File.separator), is(true)); // false for: parent, child assertThat(serverConfiguration.isUiSchemaFolder(cwd.getAbsolutePath()), is(false)); - assertThat(serverConfiguration.isUiSchemaFolder(expected + "test/"), is(false)); + assertThat(serverConfiguration.isUiSchemaFolder(expected + "test" + File.separator), is(false)); } @Test @@ -106,7 +108,8 @@ public void isValidFileURI() { public void getWorkspaceEntries() { assumeThat(getCWD().getName(), is("org.eclipse.emfcloud.modelserver.emf.tests")); serverConfiguration.setWorkspaceRoot("."); - assertThat(serverConfiguration.getWorkspaceEntries(), hasItem(endsWith("/DefaultServerConfigurationTest.class"))); + assertThat(serverConfiguration.getWorkspaceEntries(), + hasItem(File.separator + "DefaultServerConfigurationTest.class")); } // diff --git a/tests/org.eclipse.emfcloud.modelserver.tests/src/org/eclipse/emfcloud/modelserver/tests/util/OSUtil.java b/tests/org.eclipse.emfcloud.modelserver.tests/src/org/eclipse/emfcloud/modelserver/tests/util/OSUtil.java new file mode 100644 index 00000000..c7bd8dbd --- /dev/null +++ b/tests/org.eclipse.emfcloud.modelserver.tests/src/org/eclipse/emfcloud/modelserver/tests/util/OSUtil.java @@ -0,0 +1,53 @@ +/******************************************************************************** + * Copyright (c) 2021 EclipseSource and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0, or the MIT License which is + * available at https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: EPL-2.0 OR MIT + ********************************************************************************/ +package org.eclipse.emfcloud.modelserver.tests.util; + +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.is; + +import java.io.File; + +import org.hamcrest.Matcher; + +public final class OSUtil { + private static String OS_NAME = System.getProperty("os.name", "unknown").toLowerCase(); + + private OSUtil() {} + + public static boolean isWindows() { return OS_NAME.contains("win"); } + + public static boolean isMac() { return OS_NAME.contains("mac"); } + + public static boolean isUnix() { + return OS_NAME.contains("nux") || OS_NAME.contains("nix") || OS_NAME.contains("aix"); + } + + public static String osLineSeparator(final String text) { + // assume linux by default + return isWindows() + ? text.replaceAll("\\n", System.lineSeparator()) + : text; + } + + public static String osFileSeparator(final String text) { + return isWindows() + ? text.replace("/", File.separator) + : text; + } + + public static Matcher osEndsWith(final String suffix) { + return endsWith(osFileSeparator(suffix)); + } + + public static Matcher osIs(final String text) { + return is(osFileSeparator(text)); + } +}