This is an automated email from the ASF dual-hosted git repository.

thiagoelg pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git


The following commit(s) were added to refs/heads/main by this push:
     new 2ee0df609d3 [kie-issues#2145] Loading WID File from /global or 
location of a BPMN file (#3371)
2ee0df609d3 is described below

commit 2ee0df609d355ae07d4343939a46818764726fae
Author: Jozef Marko <[email protected]>
AuthorDate: Wed Jan 7 12:30:26 2026 +0100

    [kie-issues#2145] Loading WID File from /global or location of a BPMN file 
(#3371)
    
    Co-authored-by: Thiago Lugli <[email protected]>
---
 packages/kie-editors-standalone/src/bpmn/index.ts  |   4 +-
 .../StandaloneEditorsEditorChannelApiImpl.ts       |   7 +-
 .../client/session/BPMNSessionInitializer.java     |  23 +-
 .../client/session/BPMNSessionInitializerTest.java |  19 +-
 .../WorkItemDefinitionStandaloneClientService.java |  44 +++-
 .../selenium/BPMNDesignerKogitoSeleniumIT.java     |   2 +-
 .../services/BPMNStaticResourceContentService.java |  12 +-
 .../marshall/service/BPMNClientDiagramService.java |  11 +-
 .../src/VsCodeKieEditorControllerFactory.ts        |   7 -
 ...VsCodeResourceContentServiceForDanglingFiles.ts |   1 -
 .../VsCodeResourceContentServiceForWorkspaces.ts   | 144 ++++++-----
 .../VsCodeResourceContentServiceIsomorphicGitFs.ts |   9 +
 ...eResourceContentServiceForDanglingFiles.test.ts |   1 -
 ...CodeResourceContentServiceForWorkspaces.test.ts | 285 +++++++++++++++++++++
 .../vscode-extension/tests/__mocks__/vscode.ts     |  33 ++-
 .../src/context/WorkspacesContextProvider.tsx      |   4 +-
 .../src/services/WorkspaceService.tsx              |  13 +-
 .../src/worker/WorkspacesWorkerApiImpl.ts          |   1 -
 pnpm-lock.yaml                                     |  28 +-
 19 files changed, 503 insertions(+), 145 deletions(-)

diff --git a/packages/kie-editors-standalone/src/bpmn/index.ts 
b/packages/kie-editors-standalone/src/bpmn/index.ts
index 412d633f1ed..0edee4c21bb 100644
--- a/packages/kie-editors-standalone/src/bpmn/index.ts
+++ b/packages/kie-editors-standalone/src/bpmn/index.ts
@@ -88,7 +88,9 @@ export function open(args: {
     stateControl,
     {
       normalizedPosixPathRelativeToTheWorkspaceRoot: "", // FIXME: 
https://github.com/apache/incubator-kie-issues/issues/811
-      fileName: "", // FIXME: 
https://github.com/apache/incubator-kie-issues/issues/811
+      // `fileName` is needed for `widService` that loads Work Item 
Definitions in `BPMNClientDiagramService`
+      // see `transform` and `doTransform` in `BPMNClientDiagramService` and 
`WorkItemDefinitionStandaloneClientService` implementation
+      fileName: "default", // FIXME: 
https://github.com/apache/incubator-kie-issues/issues/811
       fileExtension: "bpmn",
       getFileContents: () => Promise.resolve(args.initialContent),
       isReadOnly: args.readOnly ?? false,
diff --git 
a/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
 
b/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
index c85c703b52d..8df8ab7e64e 100644
--- 
a/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
+++ 
b/packages/kie-editors-standalone/src/envelope/StandaloneEditorsEditorChannelApiImpl.ts
@@ -23,7 +23,6 @@ import {
   ResourceContentRequest,
   ResourceListRequest,
   ResourcesList,
-  ContentType,
 } from "@kie-tools-core/workspace/dist/api";
 import {
   EditorContent,
@@ -107,7 +106,11 @@ export class StandaloneEditorsEditorChannelApiImpl 
implements KogitoEditorChanne
     }
 
     const matcher = new Minimatch(request.pattern);
-    const matches = Array.from(this.resources.keys()).filter((path) => 
matcher.match(path));
+    const matches = Array.from(this.resources.keys()).filter((path) => {
+      const pathAdaptedForSlashPrefixedPattern =
+        (request.pattern.startsWith("/") && !path.startsWith("/") ? "/" : "") 
+ path;
+      return matcher.match(pathAdaptedForSlashPrefixedPattern);
+    });
     return new ResourcesList(request.pattern, matches);
   }
 
diff --git 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
index dfc5ec3e0ab..96cf87f9973 100644
--- 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
+++ 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/main/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializer.java
@@ -20,19 +20,15 @@
 
 package org.kie.workbench.common.stunner.bpmn.client.session;
 
-import java.util.Collection;
 import java.util.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 
-import elemental2.promise.Promise;
 import 
org.kie.workbench.common.stunner.bpmn.client.dataproviders.CalledElementFormProvider;
 import 
org.kie.workbench.common.stunner.bpmn.client.dataproviders.RuleFlowGroupFormProvider;
 import 
org.kie.workbench.common.stunner.bpmn.client.diagram.DiagramTypeClientService;
-import 
org.kie.workbench.common.stunner.bpmn.client.workitem.WorkItemDefinitionClientService;
 import org.kie.workbench.common.stunner.bpmn.qualifiers.BPMN;
-import org.kie.workbench.common.stunner.bpmn.workitem.WorkItemDefinition;
 import 
org.kie.workbench.common.stunner.core.client.session.impl.SessionInitializer;
 import org.kie.workbench.common.stunner.core.diagram.Metadata;
 import org.uberfire.mvp.Command;
@@ -43,18 +39,15 @@ public class BPMNSessionInitializer implements 
SessionInitializer {
 
     private static Logger LOGGER = 
Logger.getLogger(BPMNSessionInitializer.class.getName());
 
-    private final WorkItemDefinitionClientService workItemDefinitionService;
     private final DiagramTypeClientService diagramTypeService;
 
     // CDI proxy.
     protected BPMNSessionInitializer() {
-        this(null, null);
+        this(null);
     }
 
     @Inject
-    public BPMNSessionInitializer(final WorkItemDefinitionClientService 
workItemDefinitionService,
-                                  final DiagramTypeClientService 
diagramTypeService) {
-        this.workItemDefinitionService = workItemDefinitionService;
+    public BPMNSessionInitializer(final DiagramTypeClientService 
diagramTypeService) {
         this.diagramTypeService = diagramTypeService;
     }
 
@@ -64,16 +57,6 @@ public class BPMNSessionInitializer implements 
SessionInitializer {
         diagramTypeService.loadDiagramType(metadata);
         CalledElementFormProvider.initServerData();
         RuleFlowGroupFormProvider.initServerData();
-        workItemDefinitionService
-                .call(metadata)
-                .then(workItemDefinitions -> {
-                    completeCallback.execute();
-                    return null;
-                })
-                
.catch_((Promise.CatchOnRejectedCallbackFn<Collection<WorkItemDefinition>>) 
error -> {
-                    LOGGER.severe("Error obtaining the work item definitions 
[error=" + error + "]");
-                    completeCallback.execute();
-                    return null;
-                });
+        completeCallback.execute();
     }
 }
diff --git 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
index c9ce04aa08c..5b84788a740 100644
--- 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
+++ 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-client/src/test/java/org/kie/workbench/common/stunner/bpmn/client/session/BPMNSessionInitializerTest.java
@@ -20,34 +20,21 @@
 
 package org.kie.workbench.common.stunner.bpmn.client.session;
 
-import elemental2.promise.IThenable;
-import elemental2.promise.Promise;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import 
org.kie.workbench.common.stunner.bpmn.client.diagram.DiagramTypeClientService;
-import 
org.kie.workbench.common.stunner.bpmn.client.workitem.WorkItemDefinitionClientService;
 import org.kie.workbench.common.stunner.core.diagram.Metadata;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.uberfire.mvp.Command;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 @RunWith(MockitoJUnitRunner.class)
 public class BPMNSessionInitializerTest {
 
-    @Mock
-    private WorkItemDefinitionClientService workItemDefinitionService;
-
-    @Mock
-    private Promise promise;
-
     @Mock
     private DiagramTypeClientService diagramTypeService;
 
@@ -56,10 +43,7 @@ public class BPMNSessionInitializerTest {
     @Before
     @SuppressWarnings("unchecked")
     public void setUp() {
-        
doReturn(promise).when(workItemDefinitionService).call(any(Metadata.class));
-        
doReturn(promise).when(promise).then(any(IThenable.ThenOnFulfilledCallbackFn.class));
-        
doReturn(promise).when(promise).catch_(any(Promise.CatchOnRejectedCallbackFn.class));
-        tested = new BPMNSessionInitializer(workItemDefinitionService, 
diagramTypeService);
+        tested = new BPMNSessionInitializer(diagramTypeService);
     }
 
     @Test
@@ -68,6 +52,5 @@ public class BPMNSessionInitializerTest {
         Command callback = mock(Command.class);
         tested.init(metadata, callback);
         verify(diagramTypeService).loadDiagramType(metadata);
-        verify(workItemDefinitionService, times(1)).call(eq(metadata));
     }
 }
diff --git 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkItemDefinitionStandaloneClientService.java
 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkI
 [...]
index a5d682bc211..a7a624f4f4f 100644
--- 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkItemDefinitionStandaloneClientService.java
+++ 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/main/java/org/kie/workbench/common/stunner/kogito/client/services/WorkItemDefinitionStandaloneClientService.java
@@ -25,6 +25,8 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -43,18 +45,22 @@ import 
org.kie.workbench.common.stunner.bpmn.workitem.WorkItemDefinitionRegistry
 import org.kie.workbench.common.stunner.core.diagram.Metadata;
 import 
org.kie.workbench.common.stunner.kogito.client.services.util.WidPresetResources;
 import 
org.kie.workbench.common.stunner.kogito.client.services.util.WorkItemIconCache;
+import org.uberfire.backend.vfs.Path;
 import org.uberfire.client.promise.Promises;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.emptyList;
 import static 
org.kie.workbench.common.stunner.bpmn.client.workitem.WorkItemDefinitionClientParser.parse;
+import static org.kie.workbench.common.stunner.core.util.StringUtils.isEmpty;
 import static org.kie.workbench.common.stunner.core.util.StringUtils.nonEmpty;
 
 @ApplicationScoped
 public class WorkItemDefinitionStandaloneClientService implements 
WorkItemDefinitionClientService {
 
+    private static Logger LOGGER = 
Logger.getLogger(WorkItemDefinitionStandaloneClientService.class.getName());
+
     private static final String RESOURCE_ALL_WID_PATTERN = "*.wid";
-    private static final String RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN = 
"global/*.wid";
+    private static final String RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN = 
"/global/*.wid";
     private static final String MILESTONE_ICON = "defaultmilestoneicon.png";
     private static final String MILESTONE_NAME = "Milestone";
 
@@ -63,10 +69,6 @@ public class WorkItemDefinitionStandaloneClientService 
implements WorkItemDefini
     private final ResourceContentService resourceContentService;
     private final WorkItemIconCache workItemIconCache;
 
-    // Cache the promise, as by definition will be performed just once,
-    // so the available work item definitions will be also just registered 
once, by app.
-    private Promise<Collection<WorkItemDefinition>> loader;
-
     @Inject
     public WorkItemDefinitionStandaloneClientService(final Promises promises,
                                                      final 
WorkItemDefinitionCacheRegistry registry,
@@ -81,7 +83,6 @@ public class WorkItemDefinitionStandaloneClientService 
implements WorkItemDefini
 
     @PostConstruct
     public void init() {
-        loader = allWorkItemsLoader();
     }
 
     @Produces
@@ -93,24 +94,38 @@ public class WorkItemDefinitionStandaloneClientService 
implements WorkItemDefini
 
     @Override
     public Promise<Collection<WorkItemDefinition>> call(final Metadata input) {
-        return loader;
+        return allWorkItemsLoader(input.getPath());
     }
 
     @PreDestroy
     public void destroy() {
         registry.clear();
-        loader = null;
     }
 
-    private Promise<Collection<WorkItemDefinition>> allWorkItemsLoader() {
+
+    private Promise<Collection<WorkItemDefinition>> allWorkItemsLoader(Path 
openedDiagramPath) {
+
+        final int lastSlashIndex = openedDiagramPath != null ? 
openedDiagramPath.toURI().lastIndexOf('/') : -1;
+        final String openedDiagramFolderRelativeToTheWorkspace = 
(lastSlashIndex != -1) 
+            ? openedDiagramPath.toURI().substring(0, lastSlashIndex + 1) 
+            : ""; 
+
+        // We construct the `widPattern` in this complicated manner because of 
multiple ResourceContentImplementations
+        // VsCodeResourceContentServiceForWorkspaces - that has access to the 
currently opened file location - SearchType.ASSET_FOLDER could be used
+        // WorkspaceService - that has no access to the currently opened file 
location - SearchType.ASSET_FOLDER could not be used
+        // As a workaround we include folder into `widPattern` and use 
SearchType.TRAVERSAL
+        final String widPattern = "/" + ((openedDiagramPath == null || 
isEmpty(openedDiagramFolderRelativeToTheWorkspace)) ?  RESOURCE_ALL_WID_PATTERN 
: openedDiagramFolderRelativeToTheWorkspace + RESOURCE_ALL_WID_PATTERN);
+        
         return promises.create((success, failure) -> {
             registry.clear();
             final List<WorkItemDefinition> loaded = new LinkedList<>();
+            LOGGER.log(Level.FINE, "Searching WID using pattern: " + 
RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN);
             resourceContentService
                     .list(RESOURCE_GLOBAL_DIRECTORY_WID_PATTERN, 
ResourceListOptions.traversal())
                     .then(paths1 -> {
+                        LOGGER.log(Level.FINE, "Searching WID using pattern: " 
+ widPattern);
                         resourceContentService
-                                .list(RESOURCE_ALL_WID_PATTERN, 
ResourceListOptions.assetFolder())
+                                .list(widPattern, 
ResourceListOptions.traversal())
                                 .then(paths2 -> {
                                     String[] paths = mergeTwoArrays(paths1, 
paths2);
                                     if (paths.length > 0) {
@@ -158,11 +173,11 @@ public class WorkItemDefinitionStandaloneClientService 
implements WorkItemDefini
     private Promise<Collection<WorkItemDefinition>> workItemsLoader(final 
String path,
                                                                     final 
Collection<WorkItemDefinition> loaded) {
         int lastDirIndex = path.lastIndexOf('/');
-        final String directory = (lastDirIndex >= 0) ? path.substring(0, 
lastDirIndex) + "/" : path;
+        final String openedDiagramFolderRelativeToTheWorkspace = (lastDirIndex 
>= 0) ? path.substring(0, lastDirIndex) + "/" : "";
         if (nonEmpty(path)) {
             return resourceContentService
                     .get(path)
-                    .then(value -> getPromises(parse(value), loaded, 
directory));
+                    .then(value -> getPromises(parse(value), loaded, 
openedDiagramFolderRelativeToTheWorkspace));
         }
         return promises.resolve(emptyList());
     }
@@ -198,7 +213,10 @@ public class WorkItemDefinitionStandaloneClientService 
implements WorkItemDefini
     }
 
     private Promise<Collection<WorkItemDefinition>> getPromises(final 
List<WorkItemDefinition> wids, final Collection<WorkItemDefinition> loaded, 
final String path) {
-        wids.forEach(w -> w.getIconDefinition().setUri(path + 
w.getIconDefinition().getUri()));
+        wids.forEach(w -> {
+            LOGGER.log(Level.FINE, "WID Icon: " + path + 
w.getIconDefinition().getUri());
+            w.getIconDefinition().setUri(path + 
w.getIconDefinition().getUri());
+        });
         return promises.create((success, failure) -> {
             promises.all(wids, this::workItemIconLoader)
                     .then(wid -> {
diff --git 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogitoSeleniumIT.java
 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogito
 [...]
index 6970f970dd8..c5bbfb3e2b5 100644
--- 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogitoSeleniumIT.java
+++ 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/selenium/BPMNDesignerKogitoSeleniumIT.java
@@ -60,7 +60,7 @@ public class BPMNDesignerKogitoSeleniumIT {
     private static final Logger LOG = 
LoggerFactory.getLogger(BPMNDesignerKogitoSeleniumIT.class);
 
     private static final String SET_CONTENT_TEMPLATE =
-            "gwtEditorBeans.get(\"BPMNDiagramEditor\").get().setContent(\"\", 
'%s')";
+            
"gwtEditorBeans.get(\"BPMNDiagramEditor\").get().setContent(\"default\", '%s')";
     private static final String GET_CONTENT_TEMPLATE =
             "return 
gwtEditorBeans.get(\"BPMNDiagramEditor\").get().getContent()";
 
diff --git 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticResourceContentService.java
 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticReso
 [...]
index 12c5656728f..8f36218bb5b 100644
--- 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticResourceContentService.java
+++ 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-kogito-runtime/src/test/java/org/kie/workbench/common/stunner/kogito/client/services/BPMNStaticResourceContentService.java
@@ -95,8 +95,6 @@ public class BPMNStaticResourceContentService implements 
ResourceContentService
             "  ]\n" +
             "]";
 
-    private static final String PATTERN_ALL_WID = "*.wid";
-    private static final String PATTERN_GLOBAL_WID = "global/*.wid";
     private static final Map<String, String> GLOBAL_WID_ENTRIES =
             new HashMap<String, String>() {{
                 put("global/default.wid", DEFAULT_DECLARATIONS);
@@ -144,14 +142,14 @@ public class BPMNStaticResourceContentService implements 
ResourceContentService
 
     @Override
     public Promise<String[]> list(final String pattern) {
-        switch (pattern) {
-            case PATTERN_GLOBAL_WID:
+        if (pattern.endsWith(".wid")) {
+            if (pattern.contains("global")) {
                 return 
promises.resolve(GLOBAL_WID_ENTRIES.keySet().toArray(new String[0]));
-            case PATTERN_ALL_WID:
+            } else {
                 return promises.resolve(ALL_WID_ENTRIES.keySet().toArray(new 
String[0]));
-            default:
-                return promises.resolve(new String[0]);
+            }
         }
+        return promises.resolve(new String[0]);
     }
 
     @Override
diff --git 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagramService.java
 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagra
 [...]
index aeef760ffba..2ef7d0d5934 100644
--- 
a/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagramService.java
+++ 
b/packages/stunner-editors/kie-wb-common-stunner/kie-wb-common-stunner-sets/kie-wb-common-stunner-bpmn/kie-wb-common-stunner-bpmn-marshalling/src/main/java/org/kie/workbench/common/stunner/bpmn/client/marshall/service/BPMNClientDiagramService.java
@@ -22,6 +22,7 @@ package 
org.kie.workbench.common.stunner.bpmn.client.marshall.service;
 
 import java.util.Collection;
 import java.util.Objects;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
@@ -51,6 +52,7 @@ import 
org.kie.workbench.common.stunner.core.graph.content.definition.Definition
 import 
org.kie.workbench.common.stunner.core.graph.content.definition.DefinitionSet;
 import org.kie.workbench.common.stunner.core.graph.util.GraphUtils;
 import 
org.kie.workbench.common.stunner.kogito.client.service.AbstractKogitoClientDiagramService;
+import org.uberfire.backend.vfs.PathFactory;
 import org.uberfire.client.promise.Promises;
 
 import static 
org.kie.workbench.common.stunner.bpmn.util.XmlUtils.createValidId;
@@ -96,20 +98,23 @@ public class BPMNClientDiagramService extends 
AbstractKogitoClientDiagramService
     @Override
     public void transform(final String xml,
                           final ServiceCallback<Diagram> callback) {
-        doTransform(DEFAULT_DIAGRAM_ID, xml, callback);
+        doTransform(DEFAULT_DIAGRAM_ID, DEFAULT_DIAGRAM_ID, xml, callback);
     }
 
     @Override
     public void transform(final String fileName,
                           final String xml,
                           final ServiceCallback<Diagram> callback) {
-        doTransform(createDiagramTitleFromFilePath(fileName), xml, callback);
+        doTransform(createDiagramTitleFromFilePath(fileName), fileName, xml, 
callback);
     }
 
     private void doTransform(final String fileName,
+                             final String fileRelativePath,
                              final String xml,
                              final ServiceCallback<Diagram> callback) {
-        final Metadata metadata = createMetadata();
+        final Metadata metadata = createMetadata();        
+        metadata.setPath(PathFactory.newPath(fileName, fileRelativePath));
+        LOGGER.log(Level.INFO, "Loading a file: [fileRelativePath: " + 
fileRelativePath + ", fileName: " + fileName + "]");
         widService
                 .call(metadata)
                 .then(wid -> {
diff --git a/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts 
b/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts
index 79701998c8f..4095c5cab0b 100644
--- a/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts
+++ b/packages/vscode-extension/src/VsCodeKieEditorControllerFactory.ts
@@ -155,11 +155,4 @@ export class VsCodeKieEditorControllerFactory {
   private getWebviewPath(webview: Webview, relativeUriPath: string) {
     return webview.asWebviewUri(Uri.joinPath(this.context.extensionUri, 
relativeUriPath)).toString();
   }
-
-  private getParentFolder(absoluteFsPath: string) {
-    if (absoluteFsPath.includes(__path.sep)) {
-      return absoluteFsPath.substring(0, 
absoluteFsPath.lastIndexOf(__path.sep) + 1);
-    }
-    return "";
-  }
 }
diff --git 
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
 
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
index 1e21bd24503..ce2b9b3d3b7 100644
--- 
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
+++ 
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForDanglingFiles.ts
@@ -18,7 +18,6 @@
  */
 
 import {
-  ContentType,
   ResourceContent,
   ResourceContentOptions,
   ResourceContentService,
diff --git 
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
 
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
index e05423b23c6..31ab9f2a021 100644
--- 
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
+++ 
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceForWorkspaces.ts
@@ -18,7 +18,6 @@
  */
 
 import {
-  ContentType,
   ResourceContent,
   ResourceContentOptions,
   ResourceContentService,
@@ -27,15 +26,14 @@ import {
   SearchType,
 } from "@kie-tools-core/workspace/dist/api";
 
-import * as vscode from "vscode";
 import * as __path from "path";
+import * as vscode from "vscode";
 import { RelativePattern } from "vscode";
-import { listFiles } from "isomorphic-git";
-import { Minimatch } from "minimatch";
-import { ReadonlyIsomorphicGitFsForVsCodeWorkspaceFolders } from 
"./VsCodeResourceContentServiceIsomorphicGitFs";
+import { isIgnored } from "isomorphic-git";
 import { toFsPath } from "../paths/paths";
-import { getNormalizedPosixPathRelativeToWorkspaceRoot } from 
"./workspaceRoot";
 import { KogitoEditorDocument } from "../VsCodeKieEditorController";
+import { getNormalizedPosixPathRelativeToWorkspaceRoot } from 
"./workspaceRoot";
+import { ReadonlyIsomorphicGitFsForVsCodeWorkspaceFolders } from 
"./VsCodeResourceContentServiceIsomorphicGitFs";
 
 /**
  * Implementation of a ResourceContentService using the vscode apis to 
list/get assets.
@@ -60,61 +58,89 @@ export class VsCodeResourceContentServiceForWorkspaces 
implements ResourceConten
           )
         : this.args.workspaceRootAbsoluteFsPath;
 
-    // The vscode API will read all files, including the .gitignore ones,
-    // making this action is less performatic than the git ls-files which will
-    // automatically exclude the .gitignore files.
-    try {
-      console.debug("VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: Trying 
to use isomorphic-git to read dir.");
-      const normalizedPosixPathsRelativeToTheBasePath = await listFiles({
-        fs: this.isomorphicGitFs,
-        dir: this.args.workspaceRootAbsoluteFsPath,
-      });
-      console.debug("VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: Success 
on using isomorphic-git!");
-
-      const minimatch = new Minimatch(pattern);
-      const regexp = minimatch.makeRe(); // The regexp is ~50x faster than the 
direct match using glob.
-      const openFileDirectoryNormalizedPosixPathRelativeToTheWorkspaceRoot = 
__path.dirname(
-        getNormalizedPosixPathRelativeToWorkspaceRoot(this.args.document)
-      );
+    // Normalize incoming pattern to POSIX for VS Code globbing
+    const posixPattern = pattern.replace(/\\/g, "/");
+    const { leadingFolderOfPattern, trailingPattern } =
+      this.splitPosixPatternForLeadingFolderAndTrailingPattern(posixPattern);
 
-      const matchingNormalizedPosixPathsRelativeToTheBasePath = 
normalizedPosixPathsRelativeToTheBasePath.filter(
-        (p) => {
-          const matchesPattern =
-            // Adding a leading slash here to make the regex have the same 
behavior as the glob with **/* pattern.
-            regexp.test("/" + p) ||
-            // check on the asset folder for *.{ext} pattern
-            // the regex doesn't support "\" from Windows paths, requiring to 
test againts POSIX paths
-            
regexp.test(__path.posix.relative(openFileDirectoryNormalizedPosixPathRelativeToTheWorkspaceRoot,
 p));
-
-          const conformsToSearchType =
-            !opts ||
-            opts.type === SearchType.TRAVERSAL ||
-            (opts.type === SearchType.ASSET_FOLDER &&
-              __path
-                .join(baseAbsoluteFsPath, toFsPath(p))
-                .startsWith(
-                  __path.join(
-                    baseAbsoluteFsPath,
-                    
toFsPath(openFileDirectoryNormalizedPosixPathRelativeToTheWorkspaceRoot)
-                  )
-                ));
-
-          return matchesPattern && conformsToSearchType;
-        }
-      );
-      return new ResourcesList(pattern, 
matchingNormalizedPosixPathsRelativeToTheBasePath);
-    } catch (error) {
-      console.debug(
-        "VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: Failed to use 
isomorphic-git to read dir. Falling back to vscode's API.",
-        error
-      );
-      const relativePattern = new RelativePattern(baseAbsoluteFsPath, pattern);
-      const files = await vscode.workspace.findFiles(relativePattern);
-      const normalizedPosixPathsRelativeToTheWorkspaceRoot = files.map((uri) =>
-        vscode.workspace.asRelativePath(uri, false)
-      );
-      return new ResourcesList(pattern, 
normalizedPosixPathsRelativeToTheWorkspaceRoot);
+    let theMostSpecificFolder = baseAbsoluteFsPath;
+    let globRelativeToBase = posixPattern;
+
+    // In case of ASSET_FOLDER we are done, see baseAbsoluteFsPath creation
+    if (opts?.type !== SearchType.ASSET_FOLDER) {
+      theMostSpecificFolder = leadingFolderOfPattern
+        ? __path.join(baseAbsoluteFsPath, leadingFolderOfPattern)
+        : baseAbsoluteFsPath;
+      globRelativeToBase = trailingPattern || posixPattern;
     }
+
+    const relativePattern = new RelativePattern(theMostSpecificFolder, 
globRelativeToBase);
+
+    const defaultExcludes = "**/{target,dist,node_modules}";
+    const vscodeNormalizedPosixPathsRelativeToTheBasePath = (
+      await vscode.workspace.findFiles(relativePattern, defaultExcludes)
+    ).map((uri) => vscode.workspace.asRelativePath(uri, false).replace(/\\/g, 
"/"));
+
+    const isNotIgnoredPath = await Promise.all(
+      vscodeNormalizedPosixPathsRelativeToTheBasePath.map(
+        async (relativePath) =>
+          !(await isIgnored({
+            fs: this.isomorphicGitFs,
+            dir: this.args.workspaceRootAbsoluteFsPath,
+            gitdir: __path.join(this.args.workspaceRootAbsoluteFsPath, ".git"),
+            filepath: relativePath,
+          }))
+      )
+    );
+    const results = vscodeNormalizedPosixPathsRelativeToTheBasePath.filter((_, 
i) => isNotIgnoredPath[i]);
+    console.debug("VS CODE RESOURCE CONTENT API IMPL FOR WORKSPACES: VS Code 
found files %s", results);
+
+    return new ResourcesList(pattern, results);
+  }
+
+  /**
+   * Detects if a path segment contains glob "magic" characters (e.g., *, ?, 
[], {}, !, or extglobs like +(…), *(…), ?(…), !(…)).
+   * @param pathSegment - The path segment to check.
+   * @returns True if the segment contains glob magic, false otherwise.
+   */
+  private hasGlobMagic(pathSegment: string): boolean {
+    // *, ?, [], {}, !, and simple extglobs like +(…), *(…), ?(…), !(…)
+    return /[*?[\]{},!]/.test(pathSegment) || /\([^)]+\)/.test(pathSegment);
+  }
+
+  /**
+   * Splits a POSIX-style path (e.g., "a/b/c") into its non-empty segments 
["a", "b", "c"].
+   * @param path - The POSIX path string to split.
+   * @returns An array of non-empty path segments.
+   */
+  private splitPosixSegments(path: string): string[] {
+    return path.split("/").filter((s) => s.length > 0);
+  }
+
+  /**
+   * Given a posix pattern (e.g. org/model/*.txt), returns:
+   *  - staticPrefix (org/model): leading directory segments with no glob 
magic, may be empty
+   *  - remainingGlob (*.txt): the rest of the pattern (dirs + filename) 
relative to staticPrefix
+   */
+  private splitPosixPatternForLeadingFolderAndTrailingPattern(pattern: 
string): {
+    leadingFolderOfPattern: string;
+    trailingPattern: string;
+  } {
+    const segments = this.splitPosixSegments(pattern);
+
+    if (segments.length === 1) {
+      return { leadingFolderOfPattern: "", trailingPattern: segments[0] };
+    }
+
+    let i = 0;
+    while (i < segments.length && !this.hasGlobMagic(segments[i])) {
+      i++;
+    }
+
+    const leadingFolderOfPattern = segments.slice(0, i).join("/");
+    const trailingPattern = segments.slice(i).join("/") || "";
+
+    return { leadingFolderOfPattern, trailingPattern };
   }
 
   public async get(
diff --git 
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
 
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
index 4e61fb9b569..1bf43d66148 100644
--- 
a/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
+++ 
b/packages/vscode-extension/src/workspace/VsCodeResourceContentServiceIsomorphicGitFs.ts
@@ -83,4 +83,13 @@ export class 
ReadonlyIsomorphicGitFsForVsCodeWorkspaceFolders {
       console.debug("ERROR on vscode.workspace.fs.stat", "error:", error, 
"path:", contentPath);
     }
   }
+
+  async exists(path: string): Promise<boolean> {
+    try {
+      await vscode.workspace.fs.stat(vscode.Uri.file(path));
+      return true;
+    } catch {
+      return false;
+    }
+  }
 }
diff --git 
a/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
 
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
index b6f90afa2bf..68974fae77e 100644
--- 
a/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
+++ 
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForDanglingFiles.test.ts
@@ -19,7 +19,6 @@
 
 import * as __path from "path";
 import { VsCodeResourceContentServiceForDanglingFiles } from 
"@kie-tools-core/vscode-extension/dist/workspace/VsCodeResourceContentServiceForDanglingFiles";
-import { ContentType } from "@kie-tools-core/workspace/dist/api";
 
 const testWorkspaceAbsoluteFsPath = __path.resolve(__dirname, 
"test-workspace") + __path.sep;
 
diff --git 
a/packages/vscode-extension/tests/VsCodeResourceContentServiceForWorkspaces.test.ts
 
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForWorkspaces.test.ts
new file mode 100644
index 00000000000..9204814223e
--- /dev/null
+++ 
b/packages/vscode-extension/tests/VsCodeResourceContentServiceForWorkspaces.test.ts
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import * as __path from "path";
+import { VsCodeResourceContentServiceForWorkspaces } from 
"@kie-tools-core/vscode-extension/dist/workspace/VsCodeResourceContentServiceForWorkspaces";
+import { TextDocument, Uri } from "vscode";
+import * as vscode from "./__mocks__/vscode";
+import { SearchType } from "@kie-tools-core/workspace/dist/api";
+
+describe("VsCodeResourceContentServiceForWorkspaces.list", () => {
+  const defaultExcludes = "**/{target,dist,node_modules}";
+
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  describe("SearchType.Traversal from workspace root", () => {
+    const wsRoot = __path.resolve(__dirname, "test-workspace");
+    const docUri = Uri.file(__path.join(wsRoot, "resource1.txt"));
+    const listOptions = { type: SearchType.TRAVERSAL };
+
+    const resourceContentService = new 
VsCodeResourceContentServiceForWorkspaces({
+      workspaceRootAbsoluteFsPath: wsRoot,
+      document: { uri: docUri } as unknown as TextDocument,
+    });
+
+    test("Simple pattern", async () => {
+      const pattern = "*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot, 
pattern: "*.txt" }, defaultExcludes);
+    });
+
+    test("Anywhere pattern", async () => {
+      const pattern = "**/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot, 
pattern: "**/*.txt" }, defaultExcludes);
+    });
+
+    test("Specific folder pattern", async () => {
+      const pattern = "submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "*.txt",
+        },
+        defaultExcludes
+      );
+    });
+
+    test("Nested specific folder pattern", async () => {
+      const pattern = "**/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        { base: wsRoot, pattern: "**/submodule/*.txt" },
+        defaultExcludes
+      );
+    });
+
+    test("Absolute pattern", async () => {
+      const pattern = "/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "*.txt",
+        },
+        defaultExcludes
+      );
+    });
+  });
+
+  describe("SearchType.Traversal from workspace submodule", () => {
+    const wsRoot = __path.resolve(__dirname, "test-workspace");
+    const docUri = Uri.file(__path.join(wsRoot, "submodule", "resource1.txt"));
+    const listOptions = { type: SearchType.TRAVERSAL };
+
+    const resourceContentService = new 
VsCodeResourceContentServiceForWorkspaces({
+      workspaceRootAbsoluteFsPath: wsRoot,
+      document: { uri: docUri } as unknown as TextDocument,
+    });
+
+    test("Simple pattern", async () => {
+      const pattern = "*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot, 
pattern: "*.txt" }, defaultExcludes);
+    });
+
+    test("Anywhere pattern", async () => {
+      const pattern = "**/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot, 
pattern: "**/*.txt" }, defaultExcludes);
+    });
+
+    test("Specific folder pattern", async () => {
+      const pattern = "submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "*.txt",
+        },
+        defaultExcludes
+      );
+    });
+
+    test("Nested specific folder pattern", async () => {
+      const pattern = "**/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        { base: wsRoot, pattern: "**/submodule/*.txt" },
+        defaultExcludes
+      );
+    });
+
+    test("Absolute pattern", async () => {
+      const pattern = "/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "*.txt",
+        },
+        defaultExcludes
+      );
+    });
+  });
+
+  describe("SearchType.AssetFolder from workspace root", () => {
+    const wsRoot = __path.resolve(__dirname, "test-workspace");
+    const docUri = Uri.file(__path.join(wsRoot, "resource1.txt"));
+    const listOptions = { type: SearchType.ASSET_FOLDER };
+
+    const resourceContentService = new 
VsCodeResourceContentServiceForWorkspaces({
+      workspaceRootAbsoluteFsPath: wsRoot,
+      document: { uri: docUri } as unknown as TextDocument,
+    });
+
+    test("Simple pattern", async () => {
+      const pattern = "*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot, 
pattern: "*.txt" }, defaultExcludes);
+    });
+
+    test("Anywhere pattern", async () => {
+      const pattern = "**/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith({ base: wsRoot, 
pattern: "**/*.txt" }, defaultExcludes);
+    });
+
+    test("Specific folder pattern", async () => {
+      const pattern = "submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        { base: wsRoot, pattern: "submodule/*.txt" },
+        defaultExcludes
+      );
+    });
+
+    test("Nested specific folder pattern", async () => {
+      const pattern = "**/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        { base: wsRoot, pattern: "**/submodule/*.txt" },
+        defaultExcludes
+      );
+    });
+
+    test("Absolute pattern", async () => {
+      const pattern = "/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        { base: wsRoot, pattern: "/submodule/*.txt" },
+        defaultExcludes
+      );
+    });
+  });
+
+  describe("SearchType.AssetFolder from workspace submodule", () => {
+    const wsRoot = __path.resolve(__dirname, "test-workspace");
+    const docUri = Uri.file(__path.join(wsRoot, "submodule", "resource1.txt"));
+    const listOptions = { type: SearchType.ASSET_FOLDER };
+
+    const resourceContentService = new 
VsCodeResourceContentServiceForWorkspaces({
+      workspaceRootAbsoluteFsPath: wsRoot,
+      document: { uri: docUri } as unknown as TextDocument,
+    });
+
+    test("Simple pattern", async () => {
+      const pattern = "*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "*.txt",
+        },
+        defaultExcludes
+      );
+    });
+
+    test("Anywhere pattern", async () => {
+      const pattern = "**/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "**/*.txt",
+        },
+        defaultExcludes
+      );
+    });
+
+    test("Specific folder pattern", async () => {
+      const pattern = "submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "submodule/*.txt",
+        },
+        defaultExcludes
+      );
+    });
+
+    test("Nested specific folder pattern", async () => {
+      const pattern = "**/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "**/submodule/*.txt",
+        },
+        defaultExcludes
+      );
+    });
+
+    test("Absolute pattern", async () => {
+      const pattern = "/submodule/*.txt";
+      await resourceContentService.list(pattern, listOptions);
+
+      expect(vscode.workspace.findFiles).toHaveBeenCalledWith(
+        {
+          base: __path.join(wsRoot, "submodule"),
+          pattern: "/submodule/*.txt",
+        },
+        defaultExcludes
+      );
+    });
+  });
+});
diff --git a/packages/vscode-extension/tests/__mocks__/vscode.ts 
b/packages/vscode-extension/tests/__mocks__/vscode.ts
index cbdbe305fa6..dd69e6f8337 100644
--- a/packages/vscode-extension/tests/__mocks__/vscode.ts
+++ b/packages/vscode-extension/tests/__mocks__/vscode.ts
@@ -20,6 +20,7 @@
 // vscode.js
 
 import * as fs from "fs";
+import * as __path from "path";
 
 const languages = {
   createDiagnosticCollection: jest.fn(),
@@ -36,9 +37,11 @@ const vscodeWindow = {
   createTextEditorDecorationType: jest.fn(),
 };
 
-const workspace = {
+const wsRoot = __path.resolve(__dirname, "..", "test-workspace");
+
+export const workspace = {
   getConfiguration: jest.fn(),
-  workspaceFolders: [],
+  workspaceFolders: [{ uri: { fsPath: wsRoot } }],
   onDidSaveTextDocument: jest.fn(),
   fs: {
     readDirectory: (uri: any) => ({
@@ -64,6 +67,23 @@ const workspace = {
       },
     }),
   },
+
+  asRelativePath: jest.fn((uri: string | { fsPath: string }, 
_includeWorkspace?: boolean) => {
+    const abs = typeof uri === "string" ? uri : uri.fsPath;
+    console.debug(wsRoot);
+    console.debug(uri);
+    let rel = abs.startsWith(wsRoot + __path.sep) ? abs.slice(wsRoot.length + 
1) : abs;
+    return rel.replace(/\\/g, "/");
+  }),
+
+  /**
+   * This is mock for unit testing. I do not want to implement any search 
mechanism.
+   * We do not want to test correctnes of the VSCode implementation in Apache 
KIE test suite
+   * We just want to be able assert `findFiles` parameters
+   */
+  findFiles: jest.fn(async (include: RelativePattern, exclude?: any, 
maxResults?: number, token?: any) => {
+    return [];
+  }),
 };
 
 const OverviewRulerLane = {
@@ -87,6 +107,14 @@ const commands = {
   executeCommand: jest.fn(),
 };
 
+/** Just te get unit test working and be able assert `base` and `pattern` */
+class RelativePattern {
+  constructor(
+    public base: string,
+    public pattern: string
+  ) {}
+}
+
 const vscode = {
   languages,
   StatusBarAlignment,
@@ -99,6 +127,7 @@ const vscode = {
   DiagnosticSeverity,
   debug,
   commands,
+  RelativePattern,
 };
 
 module.exports = vscode;
diff --git 
a/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx 
b/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
index 84f1de1d3a0..665b89d7065 100644
--- a/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
+++ b/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
@@ -19,7 +19,7 @@
 
 import React, { useEffect, useState } from "react";
 import { useCallback, useMemo } from "react";
-import { ResourceContentOptions } from "@kie-tools-core/workspace/dist/api";
+import { ResourceContentOptions, ResourceListOptions } from 
"@kie-tools-core/workspace/dist/api";
 import { WorkspaceFile, WorkspacesContext } from "./WorkspacesContext";
 import { LocalFile } from "../worker/api/LocalFile";
 import {
@@ -486,7 +486,7 @@ export function WorkspacesContextProvider(props: Props) {
   );
 
   const resourceContentList = useCallback(
-    async (args: { workspaceId: string; globPattern: string }) =>
+    async (args: { workspaceId: string; globPattern: string; opts?: 
ResourceListOptions }) =>
       workspacesSharedWorker.withBus((workspacesWorkerBus) =>
         
workspacesWorkerBus.clientApi.requests.kieSandboxWorkspacesStorage_resourceContentList(args)
       ),
diff --git a/packages/workspaces-git-fs/src/services/WorkspaceService.tsx 
b/packages/workspaces-git-fs/src/services/WorkspaceService.tsx
index 41d69fa3196..bef8ced4bbe 100644
--- a/packages/workspaces-git-fs/src/services/WorkspaceService.tsx
+++ b/packages/workspaces-git-fs/src/services/WorkspaceService.tsx
@@ -21,7 +21,7 @@ import { encoder } from "../encoderdecoder/EncoderDecoder";
 import { downloadZip, predictLength } from "client-zip";
 import { WorkspaceDescriptor } from "../worker/api/WorkspaceDescriptor";
 import { StorageFile, StorageService } from "./StorageService";
-import { basename, join, relative } from "path";
+import { join, relative } from "path";
 import { Minimatch } from "minimatch";
 import { WorkspaceDescriptorService } from "./WorkspaceDescriptorService";
 import { BroadcasterDispatch } from "./FsService";
@@ -105,15 +105,20 @@ export class WorkspaceService {
     workspaceId: string,
     globPattern?: string
   ): Promise<WorkspaceWorkerFileDescriptor[]> {
+    const isGlobPatternSlashPrefixed = globPattern?.startsWith("/");
     const matcher = globPattern ? new Minimatch(globPattern, { dot: true }) : 
undefined;
     const gitDirAbsolutePath = this.getAbsolutePath({ workspaceId, 
relativePath: ".git" });
+    const workspaceBaseAbsolutePath = this.getAbsolutePath({ workspaceId });
 
     return this.storageService.walk({
       schema,
-      baseAbsolutePath: this.getAbsolutePath({ workspaceId }),
+      baseAbsolutePath: workspaceBaseAbsolutePath,
       shouldExcludeAbsolutePath: (absolutePath) => 
absolutePath.startsWith(gitDirAbsolutePath),
-      onVisit: async ({ relativePath }) => {
-        if (matcher && !matcher.match(basename(relativePath))) {
+      onVisit: async ({ absolutePath, relativePath }) => {
+        const searchedPath = isGlobPatternSlashPrefixed
+          ? absolutePath.slice(workspaceBaseAbsolutePath.length)
+          : relativePath;
+        if (matcher && !matcher.match(searchedPath)) {
           return undefined;
         } else {
           return { workspaceId, relativePath };
diff --git a/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts 
b/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts
index 9954bf79f3f..455ecdd935a 100644
--- a/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts
+++ b/packages/workspaces-git-fs/src/worker/WorkspacesWorkerApiImpl.ts
@@ -22,7 +22,6 @@ import {
   ResourcesList,
   ResourceContentOptions,
   ResourceContent,
-  ContentType,
 } from "@kie-tools-core/workspace/dist/api";
 import { join } from "path";
 import { GIT_DEFAULT_BRANCH } from "../constants/GitConstants";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5d19d1b89a1..3cf45846a1a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -13146,19 +13146,19 @@ importers:
         version: 3.0.5
       jest:
         specifier: ^29.7.0
-        version: 
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
+        version: 
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
       jest-junit:
         specifier: ^16.0.0
         version: 16.0.0
       jest-when:
         specifier: ^3.6.0
-        version: 
3.6.0([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))
+        version: 
3.6.0([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))
       rimraf:
         specifier: ^3.0.2
         version: 3.0.2
       ts-jest:
         specifier: ^29.1.5
-        version: 
29.1.5(@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))([email protected])
+        version: 
29.1.5(@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))([email protected])
       typescript:
         specifier: ^5.5.3
         version: 5.5.3
@@ -53176,6 +53176,10 @@ snapshots:
     dependencies:
       jest: 
29.7.0(@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected]))
 
+  
[email protected]([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))):
+    dependencies:
+      jest: 
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
+
   
[email protected]([email protected](@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected]))):
     dependencies:
       jest: 
29.7.0(@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected]))
@@ -58674,6 +58678,24 @@ snapshots:
       babel-jest: 29.7.0(@babel/[email protected])
       esbuild: 0.18.20
 
+  
[email protected](@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected])))([email protected]):
+    dependencies:
+      bs-logger: 0.2.6
+      fast-json-stable-stringify: 2.1.0
+      jest: 
29.7.0(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
+      jest-util: 29.7.0
+      json5: 2.2.3
+      lodash.memoize: 4.1.2
+      make-error: 1.3.6
+      semver: 7.5.4
+      typescript: 5.5.3
+      yargs-parser: 21.1.1
+    optionalDependencies:
+      '@babel/core': 7.16.12
+      '@jest/transform': 29.7.0
+      '@jest/types': 29.6.3
+      babel-jest: 29.7.0(@babel/[email protected])
+
   
[email protected](@babel/[email protected])(@jest/[email protected])(@jest/[email protected])([email protected](@babel/[email protected]))([email protected](@types/[email protected])([email protected])([email protected](@swc/[email protected])(@types/[email protected])([email protected])))([email protected]):
     dependencies:
       bs-logger: 0.2.6


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to