Skip to content

Commit 90c21f6

Browse files
froueneAxelRICHARD
authored andcommitted
[2143] Replace Path with String in library loading configuration
Bug: #2143 Signed-off-by: Florian ROUËNÉ <florian.rouene@obeosoft.com>
1 parent d721e40 commit 90c21f6

5 files changed

Lines changed: 111 additions & 21 deletions

File tree

CHANGELOG.adoc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
- [cleanup] The definition of the tools specific to the requirements table has been moved to the backend.
1313
As a result, the following GraphQL mutations have been removed `exposeRequirements` and `createRequirement`.
1414
- [test] Reduce our call to `DiagramNavigator#nodeWithTargetObjectLabel` which has been deprecated for removal.
15-
+ The API of `ToolTester#invokeTool` and `NodeCreationTestsService#createNode` has been updated accordingly to take a `targetObjectId` instead of a `label`.
15+
The API of `ToolTester#invokeTool` and `NodeCreationTestsService#createNode` has been updated accordingly to take a `targetObjectId` instead of a `label`.
1616
- https://github.com/eclipse-syson/syson/issues/2045[#2045] [diagrams] The service `ViewNodeService#revealCompartment` has been changed to reveal a compartment only when it is needed.
17-
+ Only reveal a compartment of a node when none of the revealed compartment can display the `targetElement`.
18-
+ If many compartment candidates exist, choose the first free form compartment.
17+
Only reveal a compartment of a node when none of the revealed compartment can display the `targetElement`.
18+
If many compartment candidates exist, choose the first free form compartment.
1919
- [services] As part of the migration to the new diagram service architecture, the following methods have been moved out of `ViewNodeService` (which as been deleted):
2020
+
2121
** `List<Element> getExposedElements(Element self, EClass domainType, List<Object> ancestors, IEditingContext editingContext, DiagramContext diagramContext)` to `DiagramQueryAQLService.getExposedElements(Element self, EClass domainType, List<Object> ancestors, IEditingContext editingContext, DiagramContext diagramContext)`
@@ -34,6 +34,8 @@ As a result, the following GraphQL mutations have been removed `exposeRequiremen
3434
** `org.eclipse.syson.diagram.common.view.services.RevealCompartmentSwitch` to `org.eclipse.syson.diagram.services.utils.RevealCompartmentSwitch`
3535
+
3636
Also, a new helper method `DiagramQueryAQLService.isNotAncestorOf(...)` has been added to support edge preconditions previously written as `aql:not graphicalEdgeSource.isAncestorOf(graphicalEdgeTarget, cache)`.
37+
- https://github.com/eclipse-syson/syson/issues/2143[#2143] [configuration] The `relativePathToDirectoryContainingLibraryFiles` field in `SysONLibraryLoadingDefinition` now expects a `String` instead of a `java.nio.file.Path`.
38+
This change ensures compatibility with classpath resource resolution, which requires forward slashes (`/`) as path separators.
3739

3840
=== Dependency update
3941

@@ -53,6 +55,7 @@ Also, a new helper method `DiagramQueryAQLService.isNotAncestorOf(...)` has been
5355

5456
- https://github.com/eclipse-syson/syson/issues/2045[#2045] [diagrams] In Interconnection View diagrams, fix an issue where the `parts` compartment of a `PartDefinition` graphical node was incorrectly revealed when creating a `PartUsage` from the `PartDefinition` graphical node, even if the `interconnection` compartment was already visible.
5557
- https://github.com/eclipse-syson/syson/issues/2094[#2094] [libraries] Ensure library documents are read-only.
58+
- https://github.com/eclipse-syson/syson/issues/2143[#2143] [configuration] Fixed classpath resource resolution on Windows by enforcing forward slashes (`/`) in library paths.
5659

5760
=== Improvements
5861

backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/configuration/SysONDefaultLibrariesConfiguration.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024, 2025 Obeo.
2+
* Copyright (c) 2024, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -12,7 +12,6 @@
1212
*******************************************************************************/
1313
package org.eclipse.syson.application.configuration;
1414

15-
import java.nio.file.Paths;
1615
import java.time.Duration;
1716
import java.time.Instant;
1817
import java.util.Collections;
@@ -47,14 +46,14 @@ public class SysONDefaultLibrariesConfiguration {
4746
public static final SysONLibraryLoadingDefinition KERML = new SysONLibraryLoadingDefinition(
4847
"KerML Standard Library",
4948
ElementUtil.KERML_LIBRARY_SCHEME,
50-
Paths.get("kerml.libraries"),
49+
"kerml.libraries",
5150
Collections.singletonList(JsonResourceFactoryImpl.EXTENSION),
5251
new JSONResourceFactory()::createResource);
5352

5453
public static final SysONLibraryLoadingDefinition SYSML = new SysONLibraryLoadingDefinition(
5554
"SysML Standard Library",
5655
ElementUtil.SYSML_LIBRARY_SCHEME,
57-
Paths.get("sysml.libraries"),
56+
"sysml.libraries",
5857
Collections.singletonList(JsonResourceFactoryImpl.EXTENSION),
5958
new JSONResourceFactory()::createResource);
6059

backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/libraries/SysONLibraryLoader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2025 Obeo.
2+
* Copyright (c) 2025, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -132,7 +132,7 @@ public List<ClassPathResource> findAllLibraryResourcesFromApplicationClasspath(f
132132
final List<ClassPathResource> allResourcesForLibraryLoadingDefinition = new ArrayList<>();
133133
final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
134134
for (final String fileExtension : definition.fileExtensions()) {
135-
final String locationPattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + definition.relativePathToDirectoryContainingLibraryFiles().toString() + "/*." + fileExtension;
135+
final String locationPattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + definition.relativePathToDirectoryContainingLibraryFiles() + "/*." + fileExtension;
136136

137137
final List<org.springframework.core.io.Resource> resources = new ArrayList<>();
138138
try {
@@ -141,7 +141,7 @@ public List<ClassPathResource> findAllLibraryResourcesFromApplicationClasspath(f
141141
LOGGER.error("There was an unexpected issue while attempting to retrieve %s resources at location: %s".formatted(definition.familyName(), locationPattern), ioException);
142142
}
143143

144-
resources.stream().map(resource -> new ClassPathResource(definition.relativePathToDirectoryContainingLibraryFiles().resolve(resource.getFilename()).toString()))
144+
resources.stream().map(resource -> new ClassPathResource(definition.relativePathToDirectoryContainingLibraryFiles() + "/" + resource.getFilename()))
145145
.forEach(allResourcesForLibraryLoadingDefinition::add);
146146
}
147147

backend/application/syson-application-configuration/src/main/java/org/eclipse/syson/application/libraries/SysONLibraryLoadingDefinition.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2025 Obeo.
2+
* Copyright (c) 2025, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -12,7 +12,6 @@
1212
*******************************************************************************/
1313
package org.eclipse.syson.application.libraries;
1414

15-
import java.nio.file.Path;
1615
import java.util.List;
1716
import java.util.Objects;
1817
import java.util.function.Function;
@@ -24,7 +23,9 @@
2423
/**
2524
* Defines how to identify, retrieve and load the different files constituting a SysON library.
2625
*
27-
* Note that the resources must be in the classpath of the application.
26+
* The resources must be in the classpath of the application.
27+
* The {@code relativePathToDirectoryContainingLibraryFiles} must use forward slashes ("/") as separators,
28+
* as it is intended to be used in the classpath (e.g., JAR files or classpath directories).
2829
*
2930
* @author flatombe
3031
* @see SysONDefaultLibrariesConfiguration#KERML
@@ -33,7 +34,7 @@
3334
public record SysONLibraryLoadingDefinition(
3435
String familyName,
3536
String scheme,
36-
Path relativePathToDirectoryContainingLibraryFiles,
37+
String relativePathToDirectoryContainingLibraryFiles,
3738
List<String> fileExtensions,
3839
Function<URI, Resource> resourceLoadingBehavior) {
3940

@@ -45,9 +46,7 @@ public record SysONLibraryLoadingDefinition(
4546
* @param scheme
4647
* the (non-{@code null}) scheme to use for the EMF {@link URI}s used to load resources of this library.
4748
* @param relativePathToDirectoryContainingLibraryFiles
48-
* the (non-{@code null}) relative {@link Path} to the <b>directory</b> containing the library files. If
49-
* set to {@code foo/bar} then the library files are expected to be in directory
50-
* {@code src/main/resources/foo/bar}.
49+
* the (non-{@code null}) relative path (using forward slashes "/") to the <b>directory</b> containing the library files in the classpath.
5150
* @param fileExtensions
5251
* the (non-{@code null}) {@link List} of file extensions to look for in
5352
* {@code relativePathToDirectoryContainingLibraryFiles}.
@@ -61,11 +60,15 @@ public record SysONLibraryLoadingDefinition(
6160
Objects.requireNonNull(fileExtensions);
6261
Objects.requireNonNull(resourceLoadingBehavior);
6362

64-
if (relativePathToDirectoryContainingLibraryFiles.isAbsolute()) {
65-
throw new IllegalArgumentException("Path '%s' is absolute, but a relative one was expected.".formatted(relativePathToDirectoryContainingLibraryFiles.toString()));
63+
if (relativePathToDirectoryContainingLibraryFiles.startsWith("/")) {
64+
throw new IllegalArgumentException("Path '%s' is absolute, but a relative one was expected.".formatted(relativePathToDirectoryContainingLibraryFiles));
6665
}
67-
if (relativePathToDirectoryContainingLibraryFiles.toFile().exists() && !relativePathToDirectoryContainingLibraryFiles.toFile().isDirectory()) {
68-
throw new IllegalArgumentException("Path '%s' exists but is not a directory.".formatted(relativePathToDirectoryContainingLibraryFiles.toString()));
66+
67+
// Validate that the path does not contain Windows-style separators
68+
if (relativePathToDirectoryContainingLibraryFiles.contains("\\")) {
69+
throw new IllegalArgumentException(
70+
"Path '%s' contains Windows-style separators ('\\'). Only forward slashes ('/') are allowed for classpath resources.".formatted(relativePathToDirectoryContainingLibraryFiles)
71+
);
6972
}
7073
}
7174

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.application.configuration;
14+
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
import static org.junit.jupiter.api.Assertions.assertNotNull;
17+
import static org.junit.jupiter.api.Assertions.assertThrows;
18+
import static org.mockito.Mockito.mock;
19+
20+
import java.util.List;
21+
import java.util.function.Function;
22+
23+
import org.eclipse.emf.common.util.URI;
24+
import org.eclipse.emf.ecore.resource.Resource;
25+
import org.eclipse.syson.application.libraries.SysONLibraryLoadingDefinition;
26+
import org.junit.jupiter.api.Test;
27+
28+
/**
29+
* Test about the library loading definition.
30+
*
31+
* @author frouene
32+
*/
33+
public class SysONLibraryLoadingDefinitionTest {
34+
35+
private static final String VALID_FAMILY_NAME = "TestLibrary";
36+
private static final String VALID_SCHEME = "test";
37+
private static final String VALID_RELATIVE_PATH = "name/library";
38+
private static final List<String> VALID_EXTENSIONS = List.of("json", "xml");
39+
private static final Function<URI, Resource> VALID_LOADING_BEHAVIOR = mock(Function.class);
40+
41+
@Test
42+
void testValidDefinition() {
43+
SysONLibraryLoadingDefinition definition = new SysONLibraryLoadingDefinition(
44+
VALID_FAMILY_NAME,
45+
VALID_SCHEME,
46+
VALID_RELATIVE_PATH,
47+
VALID_EXTENSIONS,
48+
VALID_LOADING_BEHAVIOR
49+
);
50+
51+
assertNotNull(definition);
52+
assertEquals(VALID_FAMILY_NAME, definition.familyName());
53+
assertEquals(VALID_SCHEME, definition.scheme());
54+
assertEquals(VALID_RELATIVE_PATH, definition.relativePathToDirectoryContainingLibraryFiles());
55+
assertEquals(VALID_EXTENSIONS, definition.fileExtensions());
56+
assertEquals(VALID_LOADING_BEHAVIOR, definition.resourceLoadingBehavior());
57+
}
58+
59+
@Test
60+
void testAbsolutePath() {
61+
assertThrows(IllegalArgumentException.class, () ->
62+
new SysONLibraryLoadingDefinition(
63+
VALID_FAMILY_NAME,
64+
VALID_SCHEME,
65+
"/name/library",
66+
VALID_EXTENSIONS,
67+
VALID_LOADING_BEHAVIOR
68+
)
69+
);
70+
}
71+
72+
@Test
73+
void testWindowsSeparators() {
74+
assertThrows(IllegalArgumentException.class, () ->
75+
new SysONLibraryLoadingDefinition(
76+
VALID_FAMILY_NAME,
77+
VALID_SCHEME,
78+
"name\\library",
79+
VALID_EXTENSIONS,
80+
VALID_LOADING_BEHAVIOR
81+
)
82+
);
83+
}
84+
85+
}

0 commit comments

Comments
 (0)