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..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 @@ -30,21 +30,22 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.junit.Test; 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; /** - * 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 +60,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); + NamespaceUtil.addOwnedMemberTo(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); + NamespaceUtil.addOwnedMemberTo(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); + NamespaceUtil.addOwnedMemberTo(modelRootNamespace, context); assertEquals("Anything", anything.effectiveName()); assertEquals("Anything", anything.getName());