From f506b423cfe82cb46264f07f1fa94dc7856b81f5 Mon Sep 17 00:00:00 2001 From: Axel RICHARD Date: Wed, 17 Jun 2026 09:55:24 +0200 Subject: [PATCH 1/2] ST6RI-940 Fix ResourceSetModelLibraryProvider Fix ResourceSetModelLibraryProvider Implementation to take into account the root namespace Signed-off-by: Axel RICHARD --- .../ResourceSetModelLibraryProvider.java | 57 ++++++------------- .../logic/SysMLLogicStandaloneSetupTest.java | 36 +++++++----- 2 files changed, 41 insertions(+), 52 deletions(-) diff --git a/org.omg.sysml.logic/src/main/java/org/omg/sysml/logic/ResourceSetModelLibraryProvider.java b/org.omg.sysml.logic/src/main/java/org/omg/sysml/logic/ResourceSetModelLibraryProvider.java index 8759626df..da3a99f3d 100644 --- a/org.omg.sysml.logic/src/main/java/org/omg/sysml/logic/ResourceSetModelLibraryProvider.java +++ b/org.omg.sysml.logic/src/main/java/org/omg/sysml/logic/ResourceSetModelLibraryProvider.java @@ -101,8 +101,10 @@ private List getCandidateResources(ResourceSet resourceSet) { */ private Element getElement(Resource resource, String[] segments) { for (EObject object : resource.getContents()) { - if (object instanceof Element element) { - Element match = resolveElement(element, segments, 0); + // Element not contained in a Namespace can not be access using their qualified names + // Section 8.3.2.1.2 Element: "If this Element does not have an owningNamespace, then its qualifiedName is null.” + if (object instanceof Namespace namespace) { + Element match = resolveElement(namespace, segments, 0); if (match != null) { return match; } @@ -115,53 +117,30 @@ private Element getElement(Resource resource, String[] segments) { * Resolves one qualified-name segment at a time by matching the current * element and then descending through namespace memberships. */ - private Element resolveElement(Element element, String[] segments, int index) { - if (!matchesElementName(element, segments[index])) { + private Element resolveElement(Namespace namespace, String[] segments, int index) { + if (namespace == null || index >= segments.length) { return null; } - if (index == segments.length - 1) { - return element; - } - - if (!(element instanceof Namespace namespace)) { - return null; - } - - String nextSegment = segments[index + 1]; - for (Membership membership : getOwnedMemberships(namespace)) { + String currentSegment = segments[index]; + for (Membership membership : namespace.getOwnedMembership()) { Element member = membership.getMemberElement(); - if (member == null || !matchesMembershipName(membership, member, nextSegment)) { - continue; - } - - if (index + 1 == segments.length - 1) { - return member; - } - Element nested = resolveElement(member, segments, index + 1); - if (nested != null) { - return nested; + if (member != null && matchesMembershipName(membership, member, currentSegment)) { + if (index == segments.length - 1) { + return member; + } else if (member instanceof Namespace namespaceMember) { + Element nested = resolveElement(namespaceMember, segments, index + 1); + if (nested != null) { + return nested; + } + } } } return null; } - /** - * Returns the memberships owned directly by a namespace using only EMF model - * state, avoiding any Xtext-specific scoping infrastructure. - */ - private List getOwnedMemberships(Namespace namespace) { - List memberships = new ArrayList<>(); - for (EObject relationship : namespace.getOwnedRelationship()) { - if (relationship instanceof Membership membership) { - memberships.add(membership); - } - } - return memberships; - } - /** * Matches a qualified-name segment against an element's declared name or * declared short name. @@ -193,6 +172,6 @@ private boolean matchesMembershipName(Membership membership, Element member, Str * Performs an exact name comparison while tolerating missing values. */ private boolean matches(String expected, String actual) { - return expected != null && actual != null && expected.equals(actual); + return expected != null && expected.equals(actual); } } diff --git a/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java b/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java index 504e8980b..2f96ab27a 100644 --- a/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java +++ b/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java @@ -29,6 +29,7 @@ import org.eclipse.emf.ecore.resource.impl.ResourceImpl; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.junit.Test; +import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.Namespace; import org.omg.sysml.lang.sysml.OwningMembership; import org.omg.sysml.lang.sysml.SysMLFactory; @@ -37,14 +38,15 @@ import org.omg.sysml.util.SysMLLibraryUtil; /** - * Verifies the plain-EMF standalone bootstrap for {@link SysMLLogicStandaloneSetup}. + * Verifies the plain-EMF standalone bootstrap for + * {@link SysMLLogicStandaloneSetup}. */ public class SysMLLogicStandaloneSetupTest { /** - * Checks that the standalone setup installs library lookup and delegate - * support without requiring any Xtext runtime bootstrap, and that invoking - * the setup multiple times remains safe for subsequent lookups. + * Checks that the standalone setup installs library lookup and delegate support + * without requiring any Xtext runtime bootstrap, and that invoking the setup + * multiple times remains safe for subsequent lookups. */ @Test public void standaloneSetupResolvesLibraryElementsWithoutXtext() { @@ -59,21 +61,23 @@ public void standaloneSetupResolvesLibraryElementsWithoutXtext() { resourceSet.getResources().add(libraryResource); resourceSet.getResources().add(modelResource); - SysMLFactory factory = SysMLFactory.eINSTANCE; + Namespace libraryRootNamespace = SysMLFactory.eINSTANCE.createNamespace(); + libraryResource.getContents().add(libraryRootNamespace); - Namespace library = factory.createNamespace(); + Namespace library = SysMLFactory.eINSTANCE.createNamespace(); library.setDeclaredName("Base"); - libraryResource.getContents().add(library); + addAsOwnedMember(libraryRootNamespace, library); - Type anything = factory.createType(); + Type anything = SysMLFactory.eINSTANCE.createType(); anything.setDeclaredName("Anything"); - OwningMembership anythingMembership = factory.createOwningMembership(); - anythingMembership.setOwnedMemberElement(anything); - library.getOwnedRelationship().add(anythingMembership); + addAsOwnedMember(library, anything); - Namespace context = factory.createNamespace(); + Namespace modelRootNamespace = SysMLFactory.eINSTANCE.createNamespace(); + modelResource.getContents().add(modelRootNamespace); + + Namespace context = SysMLFactory.eINSTANCE.createNamespace(); context.setDeclaredName("UserModel"); - modelResource.getContents().add(context); + addAsOwnedMember(modelRootNamespace, context); assertEquals("Anything", anything.effectiveName()); assertEquals("Anything", anything.getName()); @@ -83,4 +87,10 @@ public void standaloneSetupResolvesLibraryElementsWithoutXtext() { SysMLLogicStandaloneSetup.doSetup(); assertSame(anything, SysMLLibraryUtil.getLibraryType(context, "Base::Anything")); } + + private void addAsOwnedMember(Element parent, Element child) { + OwningMembership owningMembership = SysMLFactory.eINSTANCE.createOwningMembership(); + owningMembership.setOwnedMemberElement(child); + parent.getOwnedRelationship().add(owningMembership); + } } From 87cbc2e50988941970d41b8bf9086e3aa1de500b Mon Sep 17 00:00:00 2001 From: Axel RICHARD Date: Thu, 18 Jun 2026 13:42:20 +0200 Subject: [PATCH 2/2] ST6RI-940 Use existing API in SysMLLogicStandaloneSetupTest Signed-off-by: Axel RICHARD --- .../logic/SysMLLogicStandaloneSetupTest.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java b/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java index 2f96ab27a..b28af6d80 100644 --- a/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java +++ b/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/SysMLLogicStandaloneSetupTest.java @@ -29,12 +29,11 @@ import org.eclipse.emf.ecore.resource.impl.ResourceImpl; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.junit.Test; -import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.Namespace; -import org.omg.sysml.lang.sysml.OwningMembership; import org.omg.sysml.lang.sysml.SysMLFactory; import org.omg.sysml.lang.sysml.SysMLPackage; import org.omg.sysml.lang.sysml.Type; +import org.omg.sysml.util.NamespaceUtil; import org.omg.sysml.util.SysMLLibraryUtil; /** @@ -66,18 +65,18 @@ public void standaloneSetupResolvesLibraryElementsWithoutXtext() { Namespace library = SysMLFactory.eINSTANCE.createNamespace(); library.setDeclaredName("Base"); - addAsOwnedMember(libraryRootNamespace, library); + NamespaceUtil.addOwnedMemberTo(libraryRootNamespace,library); Type anything = SysMLFactory.eINSTANCE.createType(); anything.setDeclaredName("Anything"); - addAsOwnedMember(library, anything); + NamespaceUtil.addOwnedMemberTo(library, anything); Namespace modelRootNamespace = SysMLFactory.eINSTANCE.createNamespace(); modelResource.getContents().add(modelRootNamespace); Namespace context = SysMLFactory.eINSTANCE.createNamespace(); context.setDeclaredName("UserModel"); - addAsOwnedMember(modelRootNamespace, context); + NamespaceUtil.addOwnedMemberTo(modelRootNamespace, context); assertEquals("Anything", anything.effectiveName()); assertEquals("Anything", anything.getName()); @@ -87,10 +86,4 @@ public void standaloneSetupResolvesLibraryElementsWithoutXtext() { SysMLLogicStandaloneSetup.doSetup(); assertSame(anything, SysMLLibraryUtil.getLibraryType(context, "Base::Anything")); } - - private void addAsOwnedMember(Element parent, Element child) { - OwningMembership owningMembership = SysMLFactory.eINSTANCE.createOwningMembership(); - owningMembership.setOwnedMemberElement(child); - parent.getOwnedRelationship().add(owningMembership); - } }